Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as Java by registered user BlacAmDK ( 6 years ago )
package com.blacamdk.gomoku;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
/**
* Created by black on 19-2-5.
*/
public class Core {
int nil_score = 7; //Score of an empty qtuple.
int Xscore = 15; //Score of a qtuple containing one X.
int XXscore = 400; //Score of a qtuple containing two X's.
int XXXscore = 1800; //Score of a qtuple containing three X's.
int XXXXscore = 100000; //Score of a qtuple containing four X's.
int Oscore = 35; //Score of a qtuple containing one O.
int OOscore = 800; //Score of a qtuple containing two O's.
int OOOscore = 15000; //Score of a qtuple containing three O's.
int OOOOscore = 800000; //Score of a qtuple containing four O's.
int[] score_trans_table = {
nil_score, Xscore, XXscore, XXXscore, XXXXscore, 0,
Oscore, 0, 0, 0, 0, 0,
OOscore, 0, 0, 0, 0, 0,
OOOscore, 0, 0, 0, 0, 0,
OOOOscore, 0, 0, 0, 0, 0,
0};
int[] score_table, board;
int board_width;
int board_height;
int vector_length;
int draw_limit;
public Core(int n, int m) {
board_width = n;
board_height = m;
vector_length = (m + 2) * (n + 1) + 1;
draw_limit = (7 * n * m) / 10;
init_score_table();
init_board();
}
private void init_score_table(){
score_table = new int[vector_length];
for (int i = vector_length - 1; i >= 0; i--)
score_table[i] = nil_score * 20;
int
maxi = (board_width + 1) / 2,
maxj = (board_height + 1) / 2,
maxi2 = min(maxi, 4),
maxj2 = min(maxj, 4);
int i;
for (i = 1; i <= maxi2; i++) {
for (int j = 1; j <= maxj; j++) {
init_square_score(i, j);
}
}
for (; i <= maxi; i++) {
for (int j = 1; j <= maxj2; j++) {
init_square_score(i, j);
}
}
}
private void init_board() {
board = new int[vector_length];
for (int i = vector_length - 1; i >= 0; i--)
board[i] = 0;
for (int i = 0, ii = vector_length - 1; i <= board_width; i++, ii--) {
board[i] = -1;
board[ii] = -1;
}
for (int i = 0; i < vector_length; i += (board_width + 1))
board[i] = -1;
}
private void init_square_score(int i, int j){
int
ii = (board_width - i) + 1,
jj = (board_height - j) + 1;
int sc = nb_qtuples(i, j) * score_trans_table[0];
score_table[xy_to_index(i, j)] = sc;
score_table[xy_to_index(ii, j)] = sc;
score_table[xy_to_index(i, jj)] = sc;
score_table[xy_to_index(ii, jj)] = sc;
}
private int nb_qtuples(int i, int j) {
int
left = min(4, i - 1),
right = min(4, board_width - i),
up = min(4, j - 1),
down = min(4, board_height - j);
return
min(max((left + right), 3), 8) +
min(max((up + down), 3), 8) +
min(max((min(left, up) + min(right, down)), 3), 8) +
min(max((min(right, up) + min(left, down)), 3), 8) - 12;
}
private int strongest_square() {
int
score_max = 0,
count = 0,
square = xy_to_index(1, 1),
end = xy_to_index(board_width, board_height),
best_square = -1,
score;
for (; square <= end; square++) {
if (score_table[square] < score_max) {
;
} else {
score = score_table[square];
if (score > score_max) {
if (board[square] == 0) {
count = 1;
best_square = square;
score_max = score;
} else {
score_table[square] = -1;
}
} else if (board[square] != 0) {
score_table[square] = -1;
} else if (new Random().nextInt(++count) == 0) {
best_square = square;
score_max = score;
}
}
}
return best_square;
}
private void play_move(int square, int val) {
board[square] = val;
update_score_table(square, val);
score_table[square] = -1;
}
private void update_score_table(int square, int dval) {
int
x = index_to_x(square),
y = index_to_y(square),
imin = max(-4, (1 - x)),
jmin = max(-4, (1 - y)),
imax = min(0, (board_width - x - 4)),
jmax = min(0, (board_height - y - 4));
update_score_in_direction(imin, imax, square, 1, 0, dval);
update_score_in_direction(jmin, jmax, square, 0, 1, dval);
update_score_in_direction(max(imin, jmin), min(imax, jmax), square, 1, 1, dval);
update_score_in_direction(max(max((1 - y), -4), x - board_width),
min(min(0, x - 5), board_height - y - 4), square, -1, 1, dval);
}
private void update_score_in_direction(int left, int right, int square, int dx, int dy, int dval) {
if (left > right)
return;
int depl, square0, square1, square2, count, delta;
depl = xy_to_index(dx, dy);
square0 = square + (left * depl);
square1 = square + (right * depl);
square2 = square0 + (4 * depl);
square = square0;
count = 0;
while (square <= square2) {
count += board[square];
square += depl;
}
while (square0 <= square1) {
delta = score_trans_table[count] - score_trans_table[count - dval];
if (delta != 0) {
square = square0;
while (square <= square2) {
if (board[square] == 0) {
score_table[square] += delta;
}
square += depl;
}
}
square2 += depl;
count += board[square2] - board[square0];
square0 += depl;
}
}
//return -1 means game over
public int computer_plays() {
int square = strongest_square();
if (square != -1) {
play_move(square, 6);
}
return square;
}
//return -2 means cant move like this
public int human_plays(int x, int y) {
int square = xy_to_index(x, y);
if (board[square] != 0)
return -2;
play_move(square, 1);
return square;
}
private int min(int i, int j) {
return i < j ? i : j;
}
private int max(int i, int j) {
return i > j ? i : j;
}
private int xy_to_index(int x, int y) {
return board_width * y + x + y;
}
private int index_to_x(int index) {
return index % (board_width + 1);
}
private int index_to_y(int index) {
return index / (board_width + 1);
}
public void print_board(){
for (int i = 1; i <= board_width; i++) {
for (int j = 1; j <= board_height; j++) {
System.out.print(board[xy_to_index(i, j)]);
}
System.out.println();
}
System.out.println("----------");
}
public int getValByXY(int x, int y) {
return board[xy_to_index(x, y)];
}
public static void main(String[] args) {
Core core = new Core(6, 6);
System.out.println(Arrays.toString(core.score_table));
Scanner scanner = new Scanner(System.in);
while (true) {
core.print_board();
core.computer_plays();
core.print_board();
core.human_plays(scanner.nextInt(), scanner.nextInt());
}
}
}
Revise this Paste