Welcome, guest! Login / Register - Why register?
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

Your Name: Code Language: