我正在用Python 3编写井字游戏。我将木板制作成2D阵列,并具有将木板打印为网格,教程以及获取和放置输入的功能。
它具有基本的功能,可以正确显示板子,处理输入以及处理,但是我的算法有两个主要问题。他们是:
我有一个粗略的概念,即在转弯开关和博弈机制中使用“ for循环”,但是如果不平局,游戏可能会中断。
如果任何人对以下问题或一般建议有任何解决方案, 请在这里发布。
from array import *
class board:
def __init__(self, row_1, row_2, row_3):
self.row_1 = row_1
self.row_2 = row_2
self.row_3 = row_3
# full_board is two-dimensional array
self.full_board = row_1, row_2, row_3
dash = "-"
main_board = board([dash, dash, dash], [dash, dash, dash], [dash, dash,
dash,])
def board_print(board):
for row in board:
for item in row:
print(item, end = " ")
print()
def take_input():
player = input("What space would you like to mark?(From 1 through 9):")
input_process(player)
# Algorithm for player input
# Make a dictionary of player inputs as keys, and 2d array coordinates as values
# if player's input equals a dictionary value:
# take the string and split it at ":"
# assign the two numbers of the 2d dictionary value as part_1 and part_2
# change the value of the matching coordinate to a "X" or "O", on the player(sorry, I can't make good CPU.)
# else:
# print a notification that their input was invalid and recall the function
def input_process(pl_choice):
possible_inputs = {"1" : "0:0", "2" : "0:1", "3" : "0:2", "4" : "1:0", "5" : "1:1", "6" : "1:2", "7": "2:0", "8" : "2:1", "9" : "2:2"}
if pl_choice in possible_inputs:
confirm = input("Are you sure you want to select %s? y/n: "%pl_choice)
if confirm == "y":
choice = possible_inputs[pl_choice].split(":")
answer_p1 = choice[0]
answer_p2 = choice[1]
choice_parts = [answer_p1, answer_p2]
elif confirm == "n":
print("Oh. Well you can try again.\n")
take_input()
elif pl_choice not in possible_inputs or not pl_choice.isdigit():
print("Your choice was invalid. Please try again.")
take_input()
def change_board(play_board, player_id, input_p1, input_p2):
if player_id == 1:
play_board[input_p1][input_p2] = "X"
elif player_id == 2:
play_board[input_p1][input_p2] = "O"
def tutorial():
print("Welcome to the Tic-Tac-Toe tutorial.\n")
print("This version of Tic-Tac-Toe is two-player only, although CPU may be added in the future. To play, \nYou input a number, 1-9. The numbers bind like so: ")
tutorial_board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(board_print(tutorial_board))
print("Otherwise, this plays like on paper; get 3 in a row vertically, horizontally, or diagonally before your opponent, and you win.")
# Placeholder for main game
def main_game():
print("Hello, and welcome to Tic-Tac-Toe.\nWould you like to see the tutorial? y/n:")
tutorial_needed = input
if tutorial_needed == "y":
tutorial()
elif tutorial_needed == "n":
print("Okay. Let's start!")
game_end = False
actual_board = main_board.full_board
board_print(actual_board)
take_input()
答案 0 :(得分:0)
我们为玩家X定义了一个“胜利”,条件是以下情况之一为“真”:
行只是元组中的子列表(这是您使用的类型),因此我们只需编写board[row]
即可获得一行。要检查any
(注意代码格式)行是否包含“ X”,我们必须检查all
的值是否等于“ X”。因此,我们可以写any(all(field == 'X' for field in row) for row in board)
。
列更加复杂,因为我们必须使用索引。但是,基本上,这是同一回事,反之亦然:any
列中有all
个字段“ X”:
any(all(board[row][column] == 'X' for row in range(3)) for column in range(3))
对角线:我们每个只有一条线,所以我们只需要一个循环。
对于TL-> BR,两个索引相等。因此,我们希望索引相等的字段all
等于“ X”。 all(board[i][i] == 'X' for i in range(3))
对于BL-> TR,一个索引为2-other_index
(不是 3,因为序列是零索引的)。我们希望具有两个索引的all
字段等于“ X” all(board[i][2-i] for i in range(3))
问题:如果将i
和2-i
取反会发生什么?如果您不知道,请打印出来。
您可能想编写一个check_win(board, player)
函数来为通用player
做以上所有操作-在这里是“ X”或“ O”,但是,如果您决定在其中包含三个播放器稍后再放一个更大的板子...
如果您确实要创建CPU,那么这是个错误的提出问题的地方。 如果要创建(简单的)AI,请继续阅读。如果您想使其复杂,请提出一个新问题。
考虑它应该做什么:
虽然在这种情况下,仅模拟几个转弯并选择最有可能获胜的转弯,问自己上面的问题,并编写适用于(很多)更大的板子的东西可能会更简单,有趣。
一种可能性是:
您有一个播放器序列(str,list或tuple),例如:"XO"
和一个round_counter
变量,该变量总是增加的。然后,您使用PLAYERS[round_counter % len(PLAYERS)]
获取当前玩家。使用模数运算符%
始终可获得有效的索引。
替代:
cycle('ABCD')-> A B C D A B C D A B C D ...
这很容易(for current_player in itertools.cycle("XO"):
),但是使用第一种方法时,您可以受益于拨打号码的enumerate(itertools.cycle("XO"))
,并且可以限制库的使用(如果此代码显示为某人,您可能想解释一下它的工作原理。
当all
字段为not
为空(在您的情况下为!=
短划线)时,将发生抽奖;这等效于说not
any
字段带有破折号。
请参见list comprehension来展平木板:
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
-倒数第二个示例