Chinese Checker
Game logic
Game Logic code
def init_game(game_settings):
state = {
"player_turn_idx": 0,
"board": [[-1]*9 for i in range(9)],
"players": [[None]*10, [None]*10],
"last_jumped": None,
"turn": 0
}
count = 0
for i in range(4):
for j in range(i+1):
_set_piece(state, 0, count, 3 - i, j)
_set_piece(state, 1, count, 5 + i, 8 - j)
count += 1
return state
def move(state, piece_idx, x, y):
if not _within_bound(x, y):
raise InvalidActionError("Coordinte out of bound. Should be between 0 and 8.")
if piece_idx < 0 or piece_idx >= 10:
raise InvalidActionError("piece_idx out of bound. Should be between 0 and 9.")
board = state['board']
if board[x][y] != -1:
raise InvalidActionError("There is already a piece at this target coordinate.")
player_turn_idx = state['player_turn_idx']
start = state['players'][player_turn_idx][piece_idx]
start_x = start['x']
start_y = start['y']
if _is_adjacent(start_x, start_y, x, y):
if state['last_jumped'] is not None:
raise InvalidActionError("This piece must be used to jump over another piece.")
board[start_x][start_y] = -1
_set_piece(state, player_turn_idx, piece_idx, x, y)
state['player_turn_idx'] = (player_turn_idx + 1)%2
state['turn'] += 1
return state
skipped = _is_skip_adjacent(start_x, start_y, x, y)
if skipped and board[skipped[0]][skipped[1]] != -1:
if state['last_jumped'] is not None:
last_jumped = state['last_jumped']
if last_jumped['piece_idx'] != piece_idx:
raise InvalidActionError(f"Must use piece {piece_idx} to jump or make a done_move.")
if last_jumped['last_x'] == x and last_jumped['last_y'] == y:
raise InvalidActionError(f"Cannot jump back to a previous location.")
state['board'][start_x][start_y] = -1
_set_piece(state, player_turn_idx, piece_idx, x, y)
state['last_jumped'] = {
'piece_idx': piece_idx,
'last_x': start_x,
'last_y': start_y
}
return state
raise InvalidActionError("Cannot move this piece to the target position.")
def done_move(state):
if state['last_jumped'] is None:
raise InvalidActionError(f"Cannot make a done_move when you haven't jumped previously.")
state['player_turn_idx'] = (state['player_turn_idx'] + 1)%2
state['last_jumped'] = None
state['turn'] += 1
return state
def get_game_result(state):
board = state['board']
count_player_1 = 0
count_player_2 = 0
for i in range(4):
for j in range(i+1):
if board[3-i][j] == 1:
count_player_2 += 1
if board[5+i][8-j] == 0:
count_player_1 += 1
if count_player_1 == 10:
return {
"game_result": "Winner",
"winner_idx": 0
}
elif count_player_2 == 10:
return {
"game_result": "Winner",
"winner_idx": 1
}
if state['turn'] >= 300:
if count_player_1 == 0 and count_player_2 == 0:
return {
"game_result": "Draw",
}
return {
"game_result": "Winner",
"winner_idx": 0 if count_player_1 > count_player_2 else 1
}
return {
"game_result": "NoWinnerYet",
}
def _within_bound(x, y):
if x < 0 or y < 0 or x >= 9 or y >= 9:
return False
return True
def _set_piece(state, player_idx, piece_idx, x, y):
state["board"][x][y] = player_idx
state["players"][player_idx][piece_idx] = {
"x": x,
"y": y
}
def _is_adjacent(start_x, start_y, target_x, target_y):
directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, -1), (-1, 1)]
for dir_x, dir_y in directions:
if target_x - start_x == dir_x and target_y - start_y == dir_y:
return True
return False
def _is_skip_adjacent(start_x, start_y, target_x, target_y):
directions = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, -1), (-1, 1)]
for dir_x, dir_y in directions:
if target_x - start_x == dir_x*2 and target_y - start_y == dir_y*2:
return (start_x + dir_x, start_y + dir_y)
return None
Game state schema
message State {
// Required field to indicate the player who should be making the next move
// Values = 0 or 1
int32 player_turn_idx = 1;
repeated int32 board = 2;
}
Action schema
move(int piece_idx, int x, int y)
done_move()
Last updated