首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tic Tac脚趾游戏序列发生器

Tic Tac脚趾游戏序列发生器
EN

Code Review用户
提问于 2015-02-19 22:45:39
回答 1查看 382关注 0票数 4

我希望我的代码可以写到一个.csv文件中,一堆Toe游戏的模式(30000)。我希望有9列编号从1到9,并在每一个有在网格中的数目,是在那个回合中播放的。接下来是包含整个序列的列,然后是第一个玩家的移动,第二个玩家的移动,然后是赢家。不过,我的代码效率非常低,已经运行了几个小时(我还需要第二个玩家有点聪明,但我不能使用以前游戏中的数据来实现这一点)。

代码语言:javascript
复制
import csv
import random

class TotitoGeneratorManager:
    def __init__(self, path, games):
        self.path = path
        self.games = games
        self.winner = None
        self.player1 = []
        self.player2 = []
        self.gamesequence = []
        self.turns = 0
        self.gameover = False

    def game(self):
        while self.games > 0:
            while not self.gameover:
                while self.turns > 4:
                    player1play()
                    player2play()
                if self.turns > 4:
                    winner()
                    if self.gameover:
                        write_game()
                        self.games -= 1
                    else:
                        player1play()
                        player2play()


    def player1play(self):
        play = random.randint(0,9)
        played = False
        while not played:
            if play not in self.gamesequence:
                self.player1.append(play)
                self.gamesequence.append(play)
                played = True
                self.turns +=1
            else:
                play = random.randint(0,9)


    def player2play(self):
        played = False
        while not played:
            if 4 not in self.gamesequence:
                self.player2.append(4)
                self.gamesequence.append(4)
                played = True
                self.turns += 1
            elif 0 not in self.gamesequence:
                positions = [[1,2], [2,1], [3,6], [6,3], [4,8], [8,4]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(0)
                    self.gamesequence.append(0)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 1 not in self.gamesequence:
                positions = [[0,2], [2,0], [4,7], [7,4]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(1)
                    self.gamesequence.append(1)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 2 not in self.gamesequence:
                positions = [[0,1], [1,0], [5,8], [8,5], [6,4], [4,6]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(2)
                    self.gamesequence.append(2)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 3 not in self.gamesequence:
                positions = [[0,6], [6,0], [4,5], [5,4]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(3)
                    self.gamesequence.append(3)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 5 not in self.gamesequence:
                positions = [[2,8], [8,2], [3,4], [4,3]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(3)
                    self.gamesequence.append(3)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 6 not in self.gamesequence:
                positions = [[0,3], [3,0], [7,8], [8,7], [4,2], [2,4]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(3)
                    self.gamesequence.append(3)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 7 not in self.gamesequence:
                positions = [[6,8], [8,6], [1,4], [4,1]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(3)
                    self.gamesequence.append(3)
                    played = True
                    self.turns +=1
                else:
                    break
            elif 8 not in self.gamesequence:
                positions = [[2,5], [5,2], [0,4], [6,7], [7,6]]
                if self.player1 in positions or self.player2 in positions:
                    self.player2.append(3)
                    self.gamesequence.append(3)
                    played = True
                    self.turns +=1
                else:
                    break
            else:
                play = random.randint(0,9)
                played2 = False
                while not played2:
                    if play not in self.gamesequence:
                        self.player2.append(play)
                        self.gamesequence.append(play)
                        played = True
                        played2 = True
                        self.turns +=1
                    else:
                        play = random.randint(0,9)

    def winner(self):
        winning_positions = [[0,1,2], [3,45], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]]
         if self.player1 in winning_positions:
            self.winner == 1
            self.gameover = True
        elif self.player2 in winning_positions:
            self.winner == 1
            self.gameover = True
        elif self.turns == 9:
            self.winner = 'E'
            self.gameover = True

    def create_csv(self):
        with open(self.path, 'wb') as write_file:
            header = [[1, 2, 3, 4, 5, 6, 7, 8, 9, "Secuencia", "Tiros A", "Tiros B", "Ganador"]]
            for row in header:
                for column in row:
                    write_file.write('%s,' % column)
                write_file.write('\n')

    def write_game(self):
        with open(self.path, 'wb') as write_file:
            for column in self.gamesequence:
                write_file.write('%s,' % column+1)
            write_file.write(self.gamesequence, ',')
            write_file.write(self.player1, ',')
            write_file.write(self.player2, ',')
            write_file.write(self.winner, '.')
            write_file.write('\n')
            write_file.close()

def main():
    path = "/Users/mtchavez/Assignments/CSFundamentalsUFM/totito.csv"
    games = 30000 #number of games to generate
    tgm = TotitoGeneratorManager(path, games)
    tgm.create_csv()
    tgm.game()

main()
EN

回答 1

Code Review用户

发布于 2015-02-20 00:31:20

player2play似乎是一个很长的方法,因此应该集中精力进行改进。

首先,您有大量的代码块,这些代码块是彼此之间的简单副本;我建议使用janos的技术。这意味着:

代码语言:javascript
复制
def player2play(self):
    def gamesequence 

    played = False
    while played == False:
        if 4 not in self.gamesequence:
            self.player2.append(4)
            self.gamesequence.append(4)
            played = True
            self.turns += 1
        elif 0 not in self.gamesequence:
            positions = [1,2], [2,1], [3,6], [6,3], [4,8], [8,4]
            if self.player1 in positions or self.player2 in positions:
                self.player2.append(0)
                self.gamesequence.append(0)
                played = True
                self.turns +=1
            else:
                break
        elif 1 not in self.gamesequence:
            positions = [0,2], [2,0], [4,7], [7,4]
            if self.player1 in positions or self.player2 in positions:
                self.player2.append(1)
                self.gamesequence.append(1)
                played = True
                self.turns +=1
            else:
                break

        # and so on ...

        else:
            play = random.randint(0,9)
            played2 = False
            while played2 == False:
                if play not in self.gamesequence:
                    self.player2.append(play)
                    self.gamesequence.append(play)
                    played = True
                    played2 = True
                    self.turns +=1
                else:
                    play = random.randint(0,9)

这只是第一步;看看每一步的差异,然后将其提取到一个循环中:

代码语言:javascript
复制
def player2play(self):
    played = False
    while played == False:
        positionss = (
            ([1, 2], [2, 1], [3, 6], [6, 3], [4, 8], [8, 4]),
            ([0, 2], [2, 0], [4, 7], [7, 4]),
            ([0, 1], [1, 0], [5, 8], [8, 5], [6, 4], [4, 6]),
            ([0, 6], [6, 0], [4, 5], [5, 4]),
            None, # 4 always matches
            ([2, 8], [8, 2], [3, 4], [4, 3]),
            ([0, 3], [3, 0], [7, 8], [8, 7], [4, 2], [2, 4]),
            ([6, 8], [8, 6], [1, 4], [4, 1]),
            ([2, 5], [5, 2], [0, 4], [4, 0], [6, 7], [7, 6]),
        )

        plays = 0, 1, 2, 3, 4, 3, 3, 3, 3

        for i in range(9):
            if i not in self.gamesequence:
                positions = positionss[i]
                play = plays[i]

                if i == 4 or self.player1 in positions or self.player2 in positions:
                    self.player2.append(play)
                    self.gamesequence.append(play)
                    played = True
                    self.turns += 1

                # Exit
                return

        # If none of the above triggered
        play = random.randint(0,9)
        played2 = False
        while played2 == False:
            if play not in self.gamesequence:
                self.player2.append(play)
                self.gamesequence.append(play)
                played = True
                played2 = True
                self.turns +=1
            else:
                play = random.randint(0,9)

played似乎也没有用;如果for中的if被击中,循环将被return退出,如果没有,while played2 == False将只在played = True之后退出。因此,我们可以有:

代码语言:javascript
复制
def player2play(self):
    positionss = (
        ([1, 2], [2, 1], [3, 6], [6, 3], [4, 8], [8, 4]),
        ([0, 2], [2, 0], [4, 7], [7, 4]),
        ([0, 1], [1, 0], [5, 8], [8, 5], [6, 4], [4, 6]),
        ([0, 6], [6, 0], [4, 5], [5, 4]),
        None, # 4 always matches
        ([2, 8], [8, 2], [3, 4], [4, 3]),
        ([0, 3], [3, 0], [7, 8], [8, 7], [4, 2], [2, 4]),
        ([6, 8], [8, 6], [1, 4], [4, 1]),
        ([2, 5], [5, 2], [0, 4], [4, 0], [6, 7], [7, 6]),
    )

    plays = 0, 1, 2, 3, 4, 3, 3, 3, 3

    for i in range(9):
        if i not in self.gamesequence:
            positions = positionss[i]
            play = plays[i]

            if i == 4 or self.player1 in positions or self.player2 in positions:
                self.player2.append(play)
                self.gamesequence.append(play)
                self.turns += 1

            # Exit
            return

    # If none of the above triggered
    play = random.randint(0,9)
    while True:
        if play not in self.gamesequence:
            self.player2.append(play)
            self.gamesequence.append(play)
            self.turns += 1
            return
        else:
            play = random.randint(0,9)

最后一个loop可以去复制play = random.randint(0, 9)

代码语言:javascript
复制
    # If none of the above triggered
    while True:
        play = random.randint(0, 9)

        if play not in self.gamesequence:
            self.player2.append(play)
            self.gamesequence.append(play)
            self.turns += 1
            return

您可以使用捕获循环主体的函数来删除它与循环之间的重复:

代码语言:javascript
复制
def player2play(self):
    positionss = (
        ([1, 2], [2, 1], [3, 6], [6, 3], [4, 8], [8, 4]),
        ([0, 2], [2, 0], [4, 7], [7, 4]),
        ([0, 1], [1, 0], [5, 8], [8, 5], [6, 4], [4, 6]),
        ([0, 6], [6, 0], [4, 5], [5, 4]),
        None, # 4 always matches
        ([2, 8], [8, 2], [3, 4], [4, 3]),
        ([0, 3], [3, 0], [7, 8], [8, 7], [4, 2], [2, 4]),
        ([6, 8], [8, 6], [1, 4], [4, 1]),
        ([2, 5], [5, 2], [0, 4], [4, 0], [6, 7], [7, 6]),
    )

    plays = 0, 1, 2, 3, 4, 3, 3, 3, 3

    def get_play():
        for i in range(9):
            if i not in self.gamesequence:
                positions = positionss[i]

                if i == 4 or self.player1 in positions or self.player2 in positions:
                    return plays[i]

                # Don't make a move
                return

        # If none of the above triggered
        while True:
            play = random.randint(0, 9)
            if play not in self.gamesequence:
                return play

    play = get_play()
    if play is not None:
        self.player2.append(play)
        self.gamesequence.append(play)
        self.turns += 1

这使我们更清楚地看到:

代码语言:javascript
复制
    for i in range(9):
        if i not in self.gamesequence:
            ...
            return

    # If none of the above triggered
    while True:
        play = random.randint(0, 9)
        if play not in self.gamesequence:
            ...

当然,if中的while True只能适用于play = 9。不如将其添加到循环中的另一种情况中:

代码语言:javascript
复制
def player2play(self):
    positionss = (
        ([1, 2], [2, 1], [3, 6], [6, 3], [4, 8], [8, 4]),
        ([0, 2], [2, 0], [4, 7], [7, 4]),
        ([0, 1], [1, 0], [5, 8], [8, 5], [6, 4], [4, 6]),
        ([0, 6], [6, 0], [4, 5], [5, 4]),
        None, # 4 always matches
        ([2, 8], [8, 2], [3, 4], [4, 3]),
        ([0, 3], [3, 0], [7, 8], [8, 7], [4, 2], [2, 4]),
        ([6, 8], [8, 6], [1, 4], [4, 1]),
        ([2, 5], [5, 2], [0, 4], [4, 0], [6, 7], [7, 6]),
        None, # 9 always matches
    )

    plays = 0, 1, 2, 3, 4, 3, 3, 3, 3, 9

    for i in range(10):
        if i not in self.gamesequence:
            positions = positionss[i]
            play = plays[i]

            if positions is None or self.player1 in positions or self.player2 in positions:
                self.player2.append(play)
                self.gamesequence.append(play)
                self.turns += 1

            return

    raise RuntimeError("Impossible state")

值得注意的是,整个plays != i是令人困惑的-为什么是0, 1, 2, 3, 4, 3, 3, 3, 3, 9?缺乏关于为什么4是特殊大小写的文档也令人困惑。

我有一种预感,其中至少有一些是程序中的bug。

注意:此代码未经测试,可能是错误的。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/82004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档