棋盘类游戏编程

  • 将对图案的操纵,转换为对变量(基本类型,二维数组)的操做;
  • 在 C++ 的范畴里,二维的棋盘一般通过vector<vector<int>>表示;
  • 向下移动 ⇒ (y+1, x),向右移动 ⇒ (y, x+1),向右下移动 ⇒ (y+1, x+1)
    • 对于只能向右下和下移动的棋类游戏而言,当走到最后一行 y==n1 时,移动方向只有一个,那就是

0. 棋盘坐标系与棋盘元素的表示



简单的L型图案(三个单元格)在棋盘中心位置的形态为:

const int coverType[4][3][2] = {
    {{0, 0}, {1, 0}, {0, 1}},
    {{0, 0}, {1, 0}, {1, 1}},
    {{0, 0}, {0, 1}, {1, 1}},
    {{0, 0}, {0, 1}, {-1, 1}},
};

当然根据坐标系设置方位的不同,最终图案的三维表示也不尽相同,只需统一即可,以及最好将坐标系的中心置于棋盘的中心位置(这样方位之间便会形成正负对称的情况);

1. 5×5 棋盘串串字连环

5×5 棋盘上的英文字母格子,规则是连接上下左右、对角线上相邻的字母,组成一个单词。

走一个格,检查一下字母;

const int dx[] = {-1, -1, -1, 1, 1, 1, 0, 0};
const int dy[] = {-1, 1, 0, -1, 1, 0, -1, 1};
                                    // 除去在保持不变的 (0, 0),棋类比赛一般不允许不走;
                                    // 代表移动的 8 个方向
bool hasWord(int y, int x, const string& word){
    if (!inRange(y, x)) return false;
    if (board[y][x] != word[0]) return false;
    if (word.size() == 1) return true;
    for (int dir = 0; dir < 8; ++dir){
        if (hasWord(y+dy[dir], x+dx[dir], word.substr(1)))
            return true;
                    // 如果当前字母匹配就之间返回,
                    // 如果失败,继续判断下一个方向;
    }
    return false;
                    // 所有的方向均不匹配
}

下面对该程序进行时间复杂度的分析。考虑最坏的情况,就是遍历全部而未找到,在全是 A 的情况下查找单词 AAAAAH,最后一个字母的查找一定失败。每个格子各有 8 个相邻的格子,函数会根君单词的长度 N 进行 N-1 次检索(为什么不是 N 呢,倒数第二个字母的八个方向调用结束,进入最后一个单词,是走不到内部的 for 循环,会在中间退出)。最终,检索的答案个数为 8N1 ,由此得知算法的时间复杂度为 O(8N)

2. 边界的判断

如棋盘的大小是 n×n ,以左上角为坐标原点(y, x)

if (y >= n || x <= n)   return false;
                            // 跳出棋盘外
if (y == n-1 && x == n-1) return true;
                            // 到达右下角
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五道口纳什

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值