# Gomoku Data and Supervised Model Requirements

![](https://raw.githubusercontent.com/fucusy/gomoku-first-move-always-win/master/opennings/pu_yue.png)


Build a model to fit a large scale dataset

## Input of the model：
Meaning of the input：15×15 board, there are 225 position on the board. Those position are either placed black piece, white piece or empty.
Possible representation in computer：225 numbers, 0 represent black piece, 1 represents white piece, 2 represents the position is empty. Of course, you can design more ways represent the input efficiently. 


## Output of the model：
Meaning of the output: which position next player should place their black piece, you are always to asked the position of the player (  ( the first player ) ) play black piece
Possibile representation in computer: a 225 dimension vector, the position with maximum number is the position to place black piece

## How to get training data and evaluation data：
In this competition, training data and evaluation data are the same


1. git clone this repository [https://github.com/fucusy/gomoku-first-move-always-win/](fucusy/gomoku-first-move-always-win)
2. Open folder `./gomoku/divided/`
3. List all the files in those sub folder, filename ending with `txt.board2action.txt` contains the data, filename ending with .txt only is not the data file.　[https://github.com/fucusy/gomoku-first-move-always-win/blob/master/gomoku/divided/h8_i8_i7_j7_j6_k5_h9_h7_g9_f10_g8_g10_i10_f7_j9/h8_i8_i7_j7_j6_k5_h9_h7_g9_f10_g8_g10_i10_f7_j9_k11.txt.board2action.txt](https://github.com/fucusy/gomoku-first-move-always-win/blob/master/gomoku/divided/h8_i8_i7_j7_j6_k5_h9_h7_g9_f10_g8_g10_i10_f7_j9/h8_i8_i7_j7_j6_k5_h9_h7_g9_f10_g8_g10_i10_f7_j9_k11.txt.board2action.txt) is one of the data file.
4. How to parse the training data from data file：
4.1 Each row of those data file is one sample, one data file may contains several samples, the example above only contains one sample
4.2 `1073741823,1073741823,1073741823,1073741823,1072693247,1073217535,1073331199,1073635327,1073176575,1073605631,1072693247,1073741823,1073741823,1073741823,1073741823:j11`，this the sample example
4.3 The data is splited by : into two parts. The left part is the input of the model which is the 15x15 board with piece placed on some position. The right part is the output of the model which is the move of next player.
4.4 Understanding the output of the model：take j11 as an example, it contains two parts, the first part is a character, the second part is a number. The character can be any character that starts from a to o, it represents the position in the first dimension, the number starts from 1 to 15, it represents the position in second dimension on the board
4.5 Understanding the input of the model：The below board_str2steps function can convert `1073741823,1073741823,1073741823,1073741823,1072693247,1073217535,1073331199,1073635327,1073176575,1073605631,1072693247,1073741823,1073741823,1073741823,1073741823` to `h8_h7`. The converted string container several position concatenated by _，h8_h7 means there are two piece on the board, because the black piece is always placed firstly. h8_h7 means place piece is placed on h8 and white piece is placed on h7
5. There are about 14 million training and evaluation samples
6. The model need to learn how to map the input to output. The model is used to predict the next move given the board.

## board_str2steps Function
```
def position2move(x, y):
    """

    :param x:
    :param y:
    :return:
    >>> position2move(6, 7)
    'g8'
    """
    return "%s%s" % (chr(x + ord('a')), y + 1)

class bit_board():
    black_mask = 0b01
    white_mask = 0b10

    def __init__(self):
        self.horizontal_ = []
        for i in range(15):
            self.horizontal_.append(0x3FFFFFFF)

    @staticmethod
    def init_from_board_str(board_str):
        b = bit_board()
        horizontal_ints = [int(x) for x in board_str.split(",")]
        for i in range(15):
            b.horizontal_[i] = 0x3FFFFFFF & horizontal_ints[i]
        return b

    def to_step_str(self):
        black_position = []
        white_position = []
        for y in range(15):
            for x in range(15):
                mask = 0b11 << (2 * x)
                fig = (mask & self.horizontal_[y]) >> (2 * x)
                if fig == self.black_mask:
                    black_position.append((x, y))
                elif fig == self.white_mask:
                    white_position.append((x, y))

        steps_strs = []
        for i in range(len(black_position) + len(white_position)):
            if i % 2 == 0:
                x, y = black_position[int(i / 2)]
            else:
                x, y = white_position[int((i - 1)/ 2)]
            steps_strs.append(position2move(x, y))
        return "_".join(steps_strs)


def board_str2steps(board_str):
    """

    :param board_str:
    :return:
    >>> board_str2steps("1073741823,1073741823,1073741823,1073741823,1073741823,1073741823,1073725439,1073709055,1073741823,1073741823,1073741823,1073741823,1073741823,1073741823,1073741823")
    'h8_h7'
    """
    b = bit_board.init_from_board_str(board_str=board_str)
    return b.to_step_str()
    
print(board_str2steps("1073741823,1073741823,1073741823,1073741823,1073741823,1073741823,1073725439,1073709055,1073741823,1073741823,1073741823,1073741823,1073741823,1073741823,1073741823"))

```

## Acknowledgements

We thank http://qiangchen.org to offer those dataset. 