前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python连连看与记忆翻牌游戏(1)

python连连看与记忆翻牌游戏(1)

作者头像
叶子陪你玩
发布2022-05-22 15:03:49
7630
发布2022-05-22 15:03:49
举报

提高编程能力,写游戏是非常好的选择

游戏综合性相对比较高的,会涉及比较多的逻辑,数据处理以及对应的问题算法,很多前沿的技术都会应用在游戏中。


接下来三篇准备写写游戏,以前写过一个记忆翻牌的游戏,和我们今天要讲的连连看是有很多相同的地方的,以及消除游戏也是一样,其中连连看难度最高。


连连看

记忆翻牌

消除游戏


这里我们只做规则图形(方形)的连连看,类似下面这种。


核心待解决的问题

  • 首先考虑采用哪种数据结构表示出画面中的内容?
  • 其次点击对应图形后如何判定符合消除规则?

数据结构:二维矩阵

代码语言:javascript
复制
[[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 同一水平线上

水平检测就是检测是否是同一个点,同时满足两者水平方向之间没有障碍物

1.2 同一竖直直线上

竖直检测就是检测是否是同一个点,同时满足两者竖直方向之间没有障碍物


2.一个拐角检测

一个拐角检测可以分解为一个水平检测和垂直检测,两个检测同时满足的时候,便可以通过一个拐角连接两点。一个拐角检测 = 水平检测 && 垂直检测。

A 点至 B 点能否连接可转化为满足任意一点:

A 点至 C 点的垂直检测,以及 C 点至 B 点的水平检测;

A 点至 D 点的水平检测,以及 D 点至 B 点的垂直检测。


3.两个拐角检测

两个拐角检测可以分解为一个拐角检测和水平检测或者垂直检测。

即:两个拐角检测 = 一个拐角检测 && (水平检测 || 竖直检测)

水平和竖直分别穿过AB共有四条线,扫描直线上所有不包含AB的点,看是否存在一个点C,满足任意一项:

  • A 点至 C 点通过水平或垂直检测,C 点至 B 点可通过一个拐角连接。(图中用 C 表示)
  • A 点至 C 点可通过一个拐角连接,C 点至 B 点通过水平或垂直连接。(图中用 C 下划线表示)

核心代码:

代码语言:javascript
复制
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.二个拐可以消除:


以上就是连连看的核心算法,之后会融合到游戏中。

预告:下篇实现游戏界面。

代码语言:javascript
复制
(全文完)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 叶子陪你玩编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.同一直线上
  • 2.一个拐角检测
  • 3.两个拐角检测
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档