type hinting and started working on cli v2

This commit is contained in:
Vincent Rodley 2025-09-16 10:15:32 +12:00
parent 7fee99cce8
commit b55ecde811
5 changed files with 92 additions and 9 deletions

View File

@ -32,7 +32,12 @@ Both game modes include:
### Player vs CPU
- Fix priority issues: sometimes the CPU prefers a vertical 3-in-a-row instead of completing a horizontal win.
- better eval heuristics
- order allowedMoves to try more promising moves first
- cache / transposition table (avoid rechecking already evaled positions)
- if a move results in a win, immediately return without recursion
- MAYBE refactor to a bitboard approach (MUCH MUCH faster cuz bitwise operations)
- parallel operations
### GUI

View File

@ -1,4 +1,4 @@
{
"display_mode": "coloured_background",
"cpu_search_depth": 6
"cpu_search_depth": 5
}

72
cli/v2.py Normal file
View File

@ -0,0 +1,72 @@
board = '0'*42
player = '1'
def clear():
print(end='\033[2J\033[1;1H',flush=True)
def prettyChar(char):
if char == "0":
return " "
elif char == "1":
return "R"
elif char == "2":
return "Y"
else:
return "C"
def printBoard():
global board
boardChunks = []
for i in range(0, len(board), 7):
chunk = board[i:i+7]
boardChunks.append(chunk)
print(" CONNECT FOUR")
print("=============================")
for chunk in boardChunks:
row = "|"
for tile in chunk:
row += f" {prettyChar(tile)} |"
print(row)
print("=============================")
def getColumn():
global player
while True:
try:
column = int(input(f"{prettyChar(player)}, where drop the tile? "))-1
return column
except ValueError:
print("bro enter an int")
def dropTile(col):
global board, player
index = next((row * 7 + col for row in range(5, -1, -1) if board[row * 7 + col] == '0'), None)
if index is None:
raise ValueError("Column is full")
board = board[:index] + str(player) + board[index+1:]
while True:
clear()
printBoard()
while True:
try:
col = getColumn()
dropTile(col)
break
except KeyboardInterrupt:
print("toodle-oo")
exit()
except:
print('monkey')
print(player)
player = "2" if player == "1" else "1"

View File

@ -99,7 +99,7 @@ def drop_tile(col_index):
target_tile.hover_colour = yellow_tile_hover
return r
def check_win():
def check_win() -> list[Button, Button, Button, Button]:
global tiles, player
colours = [yellow_tile, yellow_tile_hover] if player == "yellow" else [red_tile, red_tile_hover]
@ -122,7 +122,7 @@ def check_win():
if all(tiles[col + i][row - i].colour in colours for i in range(winCount)):
return [(col + i, row - i) for i in range(winCount)]
def is_board_full():
def is_board_full() -> bool:
for col in tiles:
for tile in col:
if tile.colour == tile_colour:
@ -140,15 +140,17 @@ def play_move(col_index: int):
return
if last_tile:
tiles[last_tile[0]][last_tile[1]].img = None
old_tile: Button = tiles[last_tile[0]][last_tile[1]]
old_tile.img = None
last_tile = (col_index, row_dropped)
wins = check_win()
if wins:
winner = player
for winX, winY in wins:
tiles[winX][winY].outline_width = 5
tiles[winX][winY].outline_colour = win_outline_colour
tile: Button = tiles[winX][winY]
tile.outline_width = 5
tile.outline_colour = win_outline_colour
board_full = True
elif is_board_full():
winner = None
@ -175,11 +177,11 @@ start_button = Button(x, y - 100, width, height, "Start Game",
lambda *_: menu_manager.change_menu("mode_pick"),
font, 50, rounding=8)
pvp_button = Button(x, y-height/1.5, width, height, "Player vs Player",
pvp_button = Button(x-50, y-height/1.5, width+100, height, "Player vs Player",
primary_colour, hover_colour, text_colour,
lambda *_: start_game("pvp"), font, 50, rounding=8)
pvc_button = Button(x, y+height/1.5, width, height, "Player vs CPU",
pvc_button = Button(x-50, y+height/1.5, width+100, height, "Player vs CPU",
primary_colour, hover_colour, text_colour,
lambda *_: start_game("cpu"), font, 50, rounding=8)

4
settings.json Normal file
View File

@ -0,0 +1,4 @@
{
"display_mode": "coloured_background",
"cpu_search_depth": 6
}