题目
刚学完python基础语法,上网找题刷。看到这道题,以为不难,谁知道用了整整一个下午= =要是考试,早不及格了。记录下自己的思路,也方便自己以后看回来自己有多幼稚。
分析题目
拿到题目首先分析一下,就是一个简单的拼数字游戏,空格旁边的数字可以和空格互换,按到1-8的顺序排序,空格放最后就完成游戏。然后询问是否继续,继续就开始,不继续就退出。
图像排列
首先这个拼图看起来是一个二维数组,元素包含1-8和一个空格。
用一个1-9的数组来实现就可以了,9在打印的时候用’ '来代替就可以了。而位置则可以用 3*i+j 的形式记录下来,如下:
数组为[1,2,3,4,5,6,7,8,9],打印出来的图像和位置可以记录为:
1 2 3 0 1 2 3*0+0 3*0+1 3*0+2
4 5 6 --> 3 4 5 --> 3*1+0 3*1+1 3*1+2
7 8 6 7 8 3*2+0 3*2+1 3*2+2
打印的代码可以这样实现:
myList = [1,2,3,4,5,6,7,8,9]
for i in range(0,3):
for j in range(0,3):
if myList[3*i+j] == 9:
print(' ',end='')
else:
print (myList[3*i+j],end=' ')
print()
数字的移动
数字的移动就是空格位置的变化,因为其他数字是没有动的。每一次移动只有1个数字和空格发生了位置互换。如下:
这里会用8和空格互换。
变换前:
1 2 3 3*0+0 3*0+1 3*0+2
4 5 6 --> 3*1+0 3*1+1 3*1+2 -->空格的位置在3*2+2,8的位置在3*2+1
7 8 3*2+0 3*2+1 3*2+2
变换后:
1 2 3 3*0+0 3*0+1 3*0+2
4 5 6 --> 3*1+0 3*1+1 3*1+2 -->空格的位置在3*2+1,8的位置在3*2+2
7 8 3*2+0 3*2+1 3*2+2
所以打印出来之后只需要记录9的位置,数字移动也只需要记录9的位置。
然后就是怎么判断有哪些方向可以移动的问题了。因为移动的时候是和9互换的,所以只需要根据9的位置,就可以判断了。一样可以根据3*i+j来判断:
- j=0时,都可以向左;j=1时,都可以向左向右;j=2时,都可以向右
- i=0时,都可以向上:i=1时,都可以向上向下;i=2时,都可以向下
然后还要判断怎么输入,和校验录入,朋友们自己想一下哈。
流程逻辑
- 初始打印
- 输出可以怎么移动,输入移动
- 数字和空格替换
- 检验是否达成游戏胜利条件
- 循环2-4
- 胜利后询问是否继续
- 继续的话循环1-5
- 不继续的话退出
思路就是这样。再往下就是代码,还是python新手学习,如果写得不够优雅,大神请高抬贵手,轻喷。
最近找到一个不错的学习交流群 78486745 ,大家一起来学习python哈。刚入群的小伙伴有python学习大礼包哦。
实现代码
import random
import sys
#num_index记录的是9的位置。
#用全局变量是不是不好?写完之后懒得改了就没有动了
num_index = 0
myList = [i for i in range(1,10)]
#初始化数组,记录下9的位置
def init_puzzle():
global num_index , myList
random.shuffle(myList)
num_index = myList.index(9)
#把列表按照3*3打印,数字9替代为空格
def print_puzzle():
for i in range(0,3):
for j in range(0,3):
if myList[3*i+j] == 9:
print(' ',end='')
else:
print (myList[3*i+j],end=' ')
print()
#传入x,y的坐标值,从0,0到2,2
#y=0时,都可以向左;y=1时,都可以向左向右;y=2时,都可以向右
#x=0时,都可以向上:x=1时,都可以向上向下;x=2时,都可以向下
def new_print_move(x,y):
#这里用字典是想看起来帅一点,不过好像没什么大用处
forwards = {'left':'false','right':'false','up':'false','down':'false'}
if x==0:
forwards['up'] = 'true'
elif x==1:
forwards['up'] = 'true';forwards['down'] = 'true'
else:
forwards['down'] = 'true'
if y==0:
forwards['left'] = 'true'
elif y==1:
forwards['left'] = 'true';forwards['right'] = 'true'
else :
forwards['right'] = 'true'
temp_list = []
for i,j in forwards.items():
if j == 'true':
temp_list.append(i)
while 1 :
action = input('please input '+str(temp_list)[1:-1].replace(',',' or')+': ')
if action == 'w':
if forwards['up'] == 'true':
return action
elif action == 's':
if forwards['down'] == 'true':
return action
elif action == 'a':
if forwards['left'] == 'true':
return action
elif action == 'd':
if forwards['right'] == 'true':
return action
elif action == 'q':
return action
#执行互换操作,用'a,s,w,d'控制
def move_puzzle(action,x,y):
global myList , num_index
if action == 'a':
myList[3*x+y] , myList[3*x+y+1] = myList[3*x+y+1] , myList[3*x+y] ; num_index += 1
elif action == 'd':
myList[3*x+y] , myList[3*x+y-1] = myList[3*x+y-1] , myList[3*x+y] ; num_index -= 1
elif action == 'w':
myList[3*x+y] , myList[3*(x+1)+y] = myList[3*(x+1)+y] , myList[3*x+y] ; num_index += 3
elif action == 's':
myList[3*x+y] , myList[3*(x-1)+y] = myList[3*(x-1)+y] , myList[3*x+y] ; num_index -= 3
#这里加个q是因为测试的时候太痛苦了,根本玩不出来 |= =
elif action == 'q':
sys.exit(1)
#检查是否完成
def check_puzzle(count):
global myList
check_list = [i for i in range(1,10)]
if myList == check_list:
print("win in {} steps".format(count))
return False
else:
return True
def main():
init_puzzle()
flag = True
count = 0
while flag:
print()
print("use 'a,d,s,w' to move , enter q to exit")
print(">>>>>>>>>>>>>>>>>>>>")
print_puzzle()
#取得上面分析说的3*i+j格式的i和j
posotion_x,posotion_y = num_index // 3 , num_index % 3
action = new_print_move(posotion_x,posotion_y)
move_puzzle(action,posotion_x,posotion_y)
count += 1
flag = check_puzzle(count)
while 1 :
again = input("y or n :")
if again == 'y':
main()
break
elif again == "n":
break
main()