1 Source Code
Đây là toàn bộ mã nguồn của Gomoku
import random
# Implement code for 3.1 here
def game_menu():
print('Gomoku Game--------------')
print("Game Menu")
print("Select this option below for game:")
print("1. Start a Game")
print("2. Print the Board")
print("3. Place a Stone")
print("4. Reset the Game")
print("5. Exit")
# Implement function 3.2
# Returns the inicial state of the game, with all the board empty
def create_board(size: int):
board = []
for i in range(size):
board.append([' ' for j in range(size)])
return board
# Implement 3.3
def is_occupied(board: list, x: int, y: int):
return board[x][y] != ' '
# Implement 3.4
# convert position type string (e.g., 5 A) -> type int (e.g., 5 0)
def convert_position(position: tuple):
return (int(position[0]), ord(position[1]) - ord('A'))
def place_on_board(board: list, stone: str, position: tuple):
position_ = convert_position(position=position)
if not is_occupied(board, x=position_[0], y=position_[1]):
board[position_[0]][position_[1]] = stone
return True
return False
# Implement 3.5
def print_board(board: list):
s = ""
size_tab = 5
size = len(board)
# Create column index (e.g., A B C)
for index in range(65, 65 + size):
s += chr(index) + "\t"
print(s.expandtabs(size_tab))
# Create grid and row index
i = 0
for row in range(size):
string = ""
for column in range(size): # Loop all value in each row
string += board[row][column] + " " + "--\t"
string = string[0:-3] + str(i)
print(string.expandtabs(size_tab))
print((size * '|\t').expandtabs(size_tab)) if (row < size - 1) else 0
i += 1
# Implement code for 3.6 here
def check_available_moves(board: list):
available_moves = []
size = len(board)
for row in range(size):
for col in range(size):
if not is_occupied(board, row, col):
available_moves.append((str(row), chr(col + ord('A'))))
return available_moves
# Implement 3.7
def get_column(board: list, i: int):
return [row[i] for row in board]
def check_sequences_horizontal(board: list):
size = len(board)
for row in range(size):
count_player1 = board[row].count('●')
count_player2 = board[row].count('○')
if (count_player1 == 5): return '●'
elif (count_player2 == 5): return '○'
else: return None
def check_sequences_vertical(board: list):
size = len(board)
for column_index in range(size):
column = get_column(board, column_index)
count_player1 = column.count('●')
count_player2 = column.count('○')
if (count_player1 == 5): return '●'
elif (count_player2 == 5): return '○'
else: return None
def check_sequences_diagonal1(board: list):
ROW = len(board)
COL = len(board)
diagonal_list = []
# There will be ROW+COL-1 lines in the output
for line in range(1, (ROW + COL)):
# Get column index of the first element
# in this line of output. The index is 0
# for first ROW lines and line - ROW for
# remaining lines
start_col = max(0, line - ROW)
# Get count of elements in this line.
# The count of elements is equal to
# minimum of line number, COL-start_col and ROW
count = min(line, (COL - start_col), ROW)
# Print elements of this line
diagonal_item = []
for j in range(0, count):
diagonal_item.append(board[min(ROW, line) - j - 1]
[start_col + j])
diagonal_list.append(diagonal_item)
for diagonal in diagonal_list:
if diagonal.count('●') == 5: return '●'
elif diagonal.count('○') == 5: return '○'
return None
def check_sequences_diagonal2(board: list):
h, w = len(board), len(board[0])
diagonal_list = [[board[h - p + q - 1][q]
for q in range(max(p-h+1, 0), min(p+1, w))]
for p in range(h + w - 1) ]
for diagonal in diagonal_list:
if diagonal.count('●') == 5: return '●'
elif diagonal.count('○') == 5: return '○'
return None
def check_for_winner(board: list):
white_stone = '○'
black_stone = '●'
sequences_horizontal = check_sequences_horizontal(board)
sequences_vertical = check_sequences_vertical(board)
sequences_diagonal1 = check_sequences_diagonal1(board)
sequences_diagonal2 = check_sequences_diagonal2(board)
for result in (sequences_horizontal, sequences_vertical,
sequences_diagonal1, sequences_diagonal2):
if result is not None: return result
if check_available_moves(board) == []:
return "Draw"
return None
# Implement code for 3.8 here
def random_computer_player(board: list, player_move: tuple):
size = len(board)
player_row, player_col = convert_position(player_move)
valid_moves = []
for i in range(-1, 2):
for j in range(-1, 2):
new_row = player_row + i
new_col = player_col + j
if 0 <= new_row < size and 0 <= new_col < size and not is_occupied(board, new_row, new_col):
valid_moves.append((str(new_row), chr(new_col + ord('A'))))
if len(valid_moves) == 0:
valid_moves = check_available_moves(board)
return random.choice(valid_moves)
# Implement code for 3.9 here
def input_choice():
choice = None
while True:
choice = input("Enter your choice (e.g. 1 2 3...): ")
if choice in ('1', '2', '3', '4', '5'):
break
return choice
def input_board_size():
board_size = None
while True:
board_size = int(input("Enter board size (9, 13, or 15): "))
if board_size in (9, 13, 15):
break
return board_size
def input_game_mode():
game_mode_str = ''
game_mode = None
while True:
game_mode = input("Choose game mode (1 - PvP, 2 - PvC). Please on input 1 or 2: ")
if game_mode in ('1', '2'):
break
match game_mode:
case '1':
game_mode_str = 'pvp'
case _:
game_mode_str = 'pvc'
return game_mode_str
def play_game():
game_board = None
game_mode = None
current_turn = '●'
while True:
game_menu()
#Input choice value
choice = input_choice()
#Match case
match choice:
case '1':
if game_board is not None:
print("A game is already in progress ^^.")
reset_choice = input("Do you want to reset and start a new game? (y/n): ")
if reset_choice.lower() == 'y':
game_board = None
else:
continue
board_size = input_board_size()
game_mode = input_game_mode()
game_board = create_board(board_size)
current_turn = '●'
case '2':
if game_board is not None:
print_board(game_board)
else:
print("No game in progress.")
case '3':
print("Lượt hiện tại:", current_turn)
if game_board is None:
print("No game in progress.")
continue
print_board(game_board)
position = input("Enter position to place a stone (e.g., '2 F'): ")
row, col = position.split()
if current_turn == '○' and game_mode == 'pvc':
print("It's not your turn.")
continue
if not place_on_board(game_board, current_turn, (row, col)):
print("Invalid position or position is already occupied.")
continue
winner = check_for_winner(game_board)
if winner is not None:
print_board(game_board)
if winner == 'Draw':
print("It's a draw!")
else:
print(f"Player {winner} wins!")
game_board = None
continue
if current_turn == '●':
current_turn = '○'
if game_mode == 'pvc' and winner is None:
computer_move = random_computer_player(game_board, (row, col))
print(f"Computer places stone at {computer_move[0]} {computer_move[1]}")
place_on_board(game_board, '○', computer_move)
winner = check_for_winner(game_board)
current_turn = '●'
if winner is not None:
print_board(game_board)
if winner == 'Draw':
print("It's a draw!")
else:
print(f"Player {winner} wins!")
game_board = None
case '4':
game_board = None
game_mode = None
current_turn = '●'
print("Game has been reset.")
case '5':
print("Exiting the game.")
break
case _:
print("Invalid choice. Please choose a valid option.")
play_game()