用Python编写经典15拼图

时间:2014-01-21 16:50:25

标签: python

我是python的新手,并试图在python中实现classic 15 puzzle的非gui版本。

目前我的代码随机生成一个包含4个其他列表的列表,每个列表包含1到16之间的数字(我使用16作为空格。)

这是生成列表的一个示例:

[['11', '14', '01', '16'], ['02', '13', '09', '06'], ['04', '05', '03', '07'], ['10', '15', '12', '08']]

我的问题是:

  1. 实现切换两个切片位置的函数的最佳方法是什么 当且仅当他们彼此相邻时?
  2. 我的嵌套方法是否是表示拼图板的最佳方式?
  3. 功能性或面向对象的方法更好吗?我在想每个瓷砖可以用移动方法表示为一个对象。
  4. 这就是我目前的情况:

    #!/usr/bin/env python3
    import random
    
    
    class game:
        def __init__(self, array):
            self.array = array
            print (array)
    
        def objects(self):
            self.objects = []
            for i in self.array:
                if len(str(i)) == 1:
                    i = '0'+str(i)
                    self.objects.append(i)
                else:
                    i = str(i)
                    self.objects.append(i)
            print (self.objects)
    
        def grid(self):
            self.grid = [[], [], [], []]
            for eachrow in range(4):
                print ("row number", eachrow)
    
    
         for eachobject in range(4):
                print ("this is a list of objects before popping:\n{0}".format(self.objects))
                k = random.randint(0, len(self.objects)-1)
                print (k)
                self.grid[eachrow].append(self.objects.pop(k))
                print (self.grid)
    
    
    def main():
        array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
        test = game(array)
        test.objects()
        test.grid()
    
    if __name__ == "__main__":
        main()
    

2 个答案:

答案 0 :(得分:1)

回答你的第三个问题:

  

功能性或面向对象的方法更好吗?我以为每个图块都可以用移动方法表示为对象。

我认为你应该根据你想要达到的目标来考虑每种方法。

如果您想要一个清晰的设计,您可能希望使用表示问题的每个实体(Tile,Game,EmptyTile等)的行为的对象来建模问题。但是,它可能不是性能最佳的系统,因为您可能会创建许多间接性。但是你也可能获得可重用性,模块化等等。

另一方面,如果你想专注于处理它们的数据和算法,你应该使用命令式方法(使用python的功能性spice)。如前所述,这可能也会更快,因为它会删除许多层次的间接。

基于你所说的(少数)事情,我会继续OOP方向。

当然,您可以使用面向对象编程并执行可怕的代码。你可以使用命令式并创建慢速程序。你应该以正确的方式做事。

答案 1 :(得分:1)

将您的大问题分解为许多小问题,并且更容易推理。

你想要实现人类玩游戏的程序吗?

如果你想询问相邻的瓷砖,我会建议一个有用的实施方法,就是给定一个正方形,给你一个关闭所有相邻正方形的列表。

也许您可能还需要一种方法来告诉您当前可以移动(/交换)哪些区块。

也许还可以告诉你瓷砖距离家的距离。

tiles_to_correct()方法可以使用它来告诉你仍需要将多少个瓷砖移动到正确的位置(即距离他们的家不是0)。 finished()返回0时,tiles_to_correct()可能会返回True。

实施所有这些可能至少可以帮助您思考并逐步编写已完成的程序,即使它们没有直接帮助。

在获得工作程序时,2D列表应该可以很好地表示问题。在尝试优化速度之前,我会先考虑它。我不会使用字符串作为瓷砖,我会使用数字,可能是0-15。如果你想将电路板显示给播放器,它就足以编写输出代码,如果要显示1到16,则输出代码加1。