所以我用 python 开发了一个小型 Tic Tac Toe 游戏,它运行得非常好,我确实在这里讨论了它以某种方式改进它。然而,我有一个巧妙的想法,让棋盘变得更大,并且实现得很好 - 除了对角线只能在方形网格上完成并且只能直接穿过中间这一事实之外。然后我添加了一种让用户修改板尺寸的方法,效果很好。这就是路障之前的样子。
import os
base_columns = [chr(x+97) for x in range(26)]
base_rows = [x for x in range(26)]
blank_spot = "-"
player_tracker = 0
player_character = ('X', 'O')
num_wins = {p:0 for p in player_character}
win_type = "Draw"
choice = ("y", "n")
game_running = True
def create_coords(s):
global coords, columns, rows
try:
y = s.index('x')
rows = base_rows[:int(s[:y])]
columns = base_columns[:int(s[y+1:])]
coords = {c:[blank_spot]*len(rows) for c in columns}
except (IndexError, ValueError):
create_coords("3x3")
def info_checker(s):
s = s.lower()
if 'x' in s and len(s) >= 3 and s.count('x') == 1:
y = s.index('x')
if y > 0 and s[:y].isnumeric() and s[y+1:].isnumeric():
return True
return False
def info_input(q, e="Not viable info"):
x = input(q)
while not(info_checker(x)):
print(e)
x = input(q)
else:
create_coords(x.lower())
def intro():
intro_text = ["Welcome to Tic Tac Toe", "The Goal is to get 3 characters in a row", "Player 1 is 'X'; Player 2 is 'O'","You play the game on a board that's a grid","You have to input coords to place your character", "To input the coord for you charcter (Ex: a0, b2, c1):", "- First, put the letter column you want", "- Second, then put the number row"]
for text in intro_text:
print(text, end="\n\n")
y = choice_input("Want to change the board size (y/n)? ")
if y == choice[0]:
board_text = ["Format: (Y)x(Z); Y is rows, Z is columns", "Ex: 3x3, 2x2, 3x2", "Note: If you enter a # greater than 26\nProgram defaluts to 3x3", "You can change this at the end of games"]
print("")
for text in board_text:
print(text, end="\n\n")
info_input("Input info to change board: ")
else:
create_coords("3x3")
print("")
input("Press enter to start playing ")
os.system('clear')
def print_board():
print(" " + " ".join([c for c in columns]), end="\n\n")
rows_formatted = []
for r in rows:
row_elements = []
for c in columns:
row_elements.append(coords[c][r])
space = " "*((len(str(r))%2)+1)
rows_formatted.append(f"{r} {space} {' | '.join(row_elements)}\n")
seperator = " " + "----"*len(columns) + "-\n"
print(seperator.join(rows_formatted))
def coord_checker(s):
try:
if len(s) == 2 and s[0].lower() in columns and int(s[1]) in rows:
if coords[s[0].lower()][int(s[1])] == blank_spot:
return True
else:
return False
except ValueError:
return False
def coord_input(q, e="Not a selectable coord"):
print(f"It's Player {player_tracker+1}'s turn ({player_character[player_tracker]})")
x = input(q)
while not(coord_checker(x)):
print(e)
x = input(q)
return x
def choice_input(q, e=f"Not '{choice[0]}' or '{choice[1]}', expecting 1 of them"):
x = input(q).lower()
while not(x in choice):
print(e)
x = input(q).lower()
return x
def place_tac(c):
global player_tracker
coords[c[0].lower()][int(c[1])] = player_character[player_tracker]
player_tracker = (player_tracker+1)%2
def someone_won():
global win_type
for c in columns:
if all([coords[c][r] == coords[c][rows[0]] != blank_spot for r in rows]):
win_type = coords[c][rows[0]]
for r in rows:
if all([coords[c][r] == coords[columns[0]][r] != blank_spot for c in columns]):
win_type = coords[columns[0]][r]
if len(rows) == len(columns):
length = len(rows)
if all([coords[columns[i]][rows[i]] == coords[columns[0]][0] != blank_spot for i in range(length)]):
win_type = coords[columns[0]][0]
elif all([coords[columns[0+i]][rows[(length-1)-i]] == coords[columns[0]][length-1] != blank_spot for i in range(length)]):
win_type = coords[columns[0]][length-1]
if win_type != "Draw":
return True
return False
def who_won():
if win_type == "Draw":
print(f"It was a draw! {num_wins['X']}-{num_wins['O']}")
else:
num_wins[win_type] += 1
print(f"{win_type} won! {num_wins['X']}-{num_wins['O']}")
def game():
turn_tracker = 0
while not(someone_won()) and turn_tracker < len(rows)*len(columns):
print_board()
c = coord_input("Choose a coord: ")
place_tac(c)
os.system('clear')
turn_tracker += 1
print_board()
who_won()
def reset():
global coords, player_tracker, win_type
coords = {c:[blank_spot]*len(rows) for c in columns}
if win_type != "Draw":
player_tracker = (player_character.index(win_type)+1)%2
win_type = "Draw"
def replay():
global game_running
x = choice_input("Do you want to keep playing (y/n)? ")
if x == choice[0]:
y = choice_input("Change the board size (y/n)? ")
if y == choice[0]:
info_input("Input info (Ex: 2x2, 3x3, 3x2) ")
os.system('clear')
else:
print("Thanks for playing")
game_running = False
intro()
while game_running:
game()
reset()
replay()
然而,在实践中,更大的棋盘会让游戏更难玩,也更难获胜。特别是因为你必须在棋盘的长度或宽度上将字符排成一行。所以一位朋友建议我获胜的方法是连续有 3 个角色 - 除非棋盘小于 3x3。
我自己已经能够完成大部分工作
判断 3 个“tac”是否连续的函数(参数“tics”是布尔列表)
def tic_tac_toe(tics):
toes = 0
if len(coords[columns[0]]) >= 3:
for t in tics:
if t:
toes += 1
if toes >= 3:
return True
else:
return all(tics)
return False
还有 2 个函数来查找谁赢得了一列或一行胜利
def find_column_tics(c):
count = 1
previous = coords[c][rows[0]]
for r in rows:
current = coords[c][r]
if current in player_character:
if r != rows[0] and previous == current:
count+=1
else:
count = 1
previous = current
if count >= 3:
return current
def find_row_tacs(r):
count = 1
previous = coords[columns[0]][r]
for c in columns:
current = coords[c][r]
if current in player_character:
if c != columns[0] and previous == current:
count+=1
else:
count = 1
previous = current
if count >= 3:
return current
在“someone_won()”中,它们看起来都是这样的
def someone_won():
global win_type
# For finding a win in columns
for c in columns:
for r in rows:
if tic_tac_toe([coords[c][i] == coords[c][r] != blank_spot for i in rows]):
win_type = find_column_tics(c)
# For finding a win in rows
for r in rows:
for c in columns:
if tic_tac_toe([coords[i][r] == coords[c][r] != blank_spot for i in columns]):
win_type = find_row_tacs(r)
这一切都非常有效,但后来我开始尝试解决对角线问题。在 4x4 棋盘中,有 8 种通过对角线取胜的方法,但不知道如何为此创建算法。我尝试了几种方法,但都不起作用。我想自己解决这个问题,但我认为没有经验,我想知道你们是否有任何想法或解决方案。在写这篇文章时,我已经尝试了 3 天找到一种方法来做到这一点,我真的希望这是可能的。
你可以尝试这样的事情:
def check_diagonals(board, color):
# upper left to bottom right
for i in range(len(board) - 2):
for j in range(len(board[0]) - 2):
if board[i][j] == color and board[i + 1][j + 1] == color and board[i + 2][j + 2] == color:
return True
# bottom left to top right
for i in range(2, len(board)):
for j in range(len(board[0]) - 2):
print(i, j)
if board[i][j] == color and board[i - 1][j + 1] == color and board[i - 2][j + 2] == color:
return True
return False
board = [
"0001",
"0010",
"0100"
]
print(check_diagonals(board, "1")) # True
因为实际上有两种方向相反的对角线,所以只需检查所有可能的对角线即可。