提高编程能力,写游戏是非常好的选择
游戏综合性相对比较高的,会涉及比较多的逻辑,数据处理以及对应的问题算法,很多前沿的技术都会应用在游戏中。
接下来三篇准备写写游戏,以前写过一个记忆翻牌的游戏,和我们今天要讲的连连看是有很多相同的地方的,以及消除游戏也是一样,其中连连看难度最高。
连连看
记忆翻牌
消除游戏
这里我们只做规则图形(方形)的连连看,类似下面这种。
核心待解决的问题
数据结构:二维矩阵
[[1 0 1 0]
[1 0 0 0]
[0 1 1 0]
[1 0 0 0]]
消除规则:
(来源:https://blog.csdn.net/liuyinghui523/article/details/111638194)
1.1 同一水平线上
水平检测就是检测是否是同一个点,同时满足两者水平方向之间没有障碍物
1.2 同一竖直直线上
竖直检测就是检测是否是同一个点,同时满足两者竖直方向之间没有障碍物
一个拐角检测可以分解为一个水平检测和垂直检测,两个检测同时满足的时候,便可以通过一个拐角连接两点。一个拐角检测 = 水平检测 && 垂直检测。
A 点至 B 点能否连接可转化为满足任意一点:
A 点至 C 点的垂直检测,以及 C 点至 B 点的水平检测;
A 点至 D 点的水平检测,以及 D 点至 B 点的垂直检测。
两个拐角检测可以分解为一个拐角检测和水平检测或者垂直检测。
即:两个拐角检测 = 一个拐角检测 && (水平检测 || 竖直检测)
水平和竖直分别穿过AB共有四条线,扫描直线上所有不包含AB的点,看是否存在一个点C,满足任意一项:
核心代码:
import numpy as np
def is_block(array,x,y):
if array[x,y]==0:
return False
else:
return True
def h(p1,p2):
if p1[0]==p2[0] and p1[1]==p2[1]:
return False
if p1[0]!=p2[0]:
return False
start_y = min(p1[1],p2[1])
end_y = max(p1[1],p2[1])
if start_y+1==end_y:
return True
for i in range(start_y+1,end_y):
if is_block(array,p1[0],i):
return False
return True
def v(p1,p2):
if p1[0]==p2[0] and p1[1]==p2[1]:
return False
if p1[1]!=p2[1]:
return False
start_x = min(p1[0],p2[0])
end_x = max(p1[0],p2[0])
if start_x+1==end_x:
return True
for i in range(start_x+1,end_x):
if is_block(array,i,p1[1]):
return False
return True
def turn_one(p1,p2):
if p1[0]==p2[0] and p1[1]==p2[1]:
return False
x1,y1 = p1
x2,y2 = p2
if is_block(array,x1,y1) and is_block(array,x2,y2):
result1 = (h(p1,(x1,y2)) and v((x1,y2),p2))
result2 = (h(p1,(x2,y1)) and v((x2,y1),p2))
if result1 or result2:
return True
else:
return False
def turn_two(p1,p2):
if p1[0]==p2[0] and p1[1]==p2[1]:
return False
x1,y1 = p1
x2,y2 = p2
if is_block(array,x1,y1) and is_block(array,x2,y2):
for y in range(0,4):
result1 = h(p1, (x1, y)) and turn_one(p2, (x1, y))
if result1:
return result1
for x in range(0,4):
result2 = v(p1,(x,y1)) and turn_one(p2,(x,y1))
if result2:
return result2
else:
return False
def remove(p1,p2):
# p1 和 p2 都在边界,可以直接删除
if (p1[0] == p2[0]) and (p1[0]==0 or p1[0]==len(array)-1):
print('上下边界可以直接删除')
elif (p1[1] == p2[1]) and (p1[1]==0 or p1[1]==len(array[0])-1):
print('上下边界可以直接删除')
elif array[p1[0],p1[1]]==array[p2[0],p2[1]]:
if h(p1,p2):
print('水平可以消除')
elif v(p1,p2):
print('垂直可以消除')
elif turn_one(p1,p2):
print('一个拐可以消除')
elif turn_two(p1,p2):
print('二个拐可以消除')
else:
print('无法删除')
if __name__ == '__main__':
array = np.array([1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0])
array = array.reshape(4,4)
print(array)
p1 = (0,0)
p2 = (3,0)
print(p1,p2,array[p1[0],p1[1]],array[p2[0],p2[1]])
result = remove(p1,p2)
测试结果:
1.边界直接删除:
2.二个拐可以消除:
以上就是连连看的核心算法,之后会融合到游戏中。
预告:下篇实现游戏界面。
(全文完)