做了一个麻将游戏规则引擎,准确的说它是一个麻将游戏状态机。可以基于它开发自己的麻将游戏。
*** 为什么需要一个规则引擎 ***
麻将游戏的灵魂是规则,人们玩麻将玩的也是规则,至于用什么打,在哪儿打,甚至跟谁打其实都是次要的。
*** 为什么是SDK? ***
麻将游戏的界面该怎么实现?
软件界面是一个和时代密切相关的事情。30年前麻将游戏基于Windows、DOS平台,20年前麻将游戏基于网页,现在开始流行手机,这和计算机技术发展密切相关。
所以界面开发应该开放给第三方,它应该是SDK,第三方可以基于它开发自己的麻将游戏。
*** 基于麻将规则引擎如何开发自己的麻将游戏 ***
麻将游戏规则引擎基于C语言。
一个最简单的麻将游戏代码为:
```C
#include <mj.h>
int main()
{
while (!mj_is_over())
{
mj_play();
}
return 0;
}
```
程序编写完成后,将它保存为文件,这里假设文件名为:game.c,然后我们用下面的命令编译:
```bash
cc -o game game.c -lmj
```
这样就会生出文件名为game的可执行程序了。
*** 玩家 ***
一局麻将游戏包括四个玩家,围圈而坐,也就是每个玩家都有自己的上家、下家和对家。
mj.h文件中定义了麻将游戏玩家的数量,它的内容为
#define PLAYER_NUMBER 4
然后定义了玩家变量:
struct Player;
struct Player *players[PLAYER_NUMBER];
玩家之间通过座位号来识别,玩家座位号按照连接到服务器的顺序排列,用函数mj_seat()可以获得玩家的座位号,所以玩家自己(简称本家)的信息位于players[mj_seat()]中。
每个玩家的信息包括手牌(初始为13张),若干牌搭(吃牌、碰牌、杠牌后形成的牌搭)。可以用函数mj_player_tile()和mj_player_set()获得它们。函数原型为:
struct Tile *mj_player_tile(struct Player *);
struct Set *mj_player_set(struct Player *);
处于行牌状态的玩家在抓牌后会有一张抓牌,可以用mj_player_pick()来获取它,函数原型为:
struct Tile *mj_player_pick(struct Player *);
*** 麻将牌 ***
一副麻将牌有136张牌,麻将牌之间通过牌面来区别,牌面就是一张刻画在麻将牌正面的图案,它包括包括花色和点数。每种牌面得麻将牌各有4张麻将牌,所以136张麻将牌总计有34种牌面。麻将牌花色包括饼、条、万、风和字5种。饼、条、万牌的点数值为1-9,是风牌的点数值包括东、南、西、北,字牌的点数值包括红中、绿发、白板。
麻将牌的大小分为(高x宽x深,单位为毫米):
54号,53x40x28
52号,51x38x27
50号,49x36x24
48号,47x35x23
46号,45x34x22
44号,43x33x22
42号,41x32x21
40号,39x29x20
玩家可以根据这个大小和比例来进行游戏界面设计。
mj.h文件中定义了麻将游戏麻将牌的结构,它的内容为:
struct Tile;
可以通过函数mj_tile_image()来获得一张麻将牌的图像数据(PNG格式),mj.h文件中定义了图像的结构,它的内容为:
struct MJImage
{
unsigned char *data;
int size;
};
mj_tile_image()函数的原型定义为:
struct MJImage * mj_tile_image(struct Tile *);
麻将牌和麻将牌之间可以连在一起,通过mj_tile_next()获得麻将牌的下一张麻将牌,它的函数原型为:
struct Tile *mj_tile_next(struct Tile *);
*** 游戏过程 ***
麻将游戏的过程比较复杂,简单来说游戏过程分为:起手牌、打牌、叫牌,各个过程由各个玩家依次循环进行,直到游戏结束。
游戏得过程在mj.h文件中通过enum State进行定义:
enum State
{
……
};
通过函数mj_state()可以获得游戏的当前过程,它的函数原型为:
enum State mj_state();
玩家还可以通过函数mj_call()来进行叫牌,它只能在叫牌期间被调用,否则无效。
通过函数mj_select()函数对手牌进行选择,它只能在打牌期间被调用,否则无效。
*** 游戏界面设计 ***
游戏界面的元素包括:牌桌、麻将牌。
根据麻将牌的大小,以及需要显示麻将牌的数量和位置,可以推算出所需正四边形牌桌的大小。
根据游戏玩家的座位,玩家位于麻将桌的四边,需要显示每个玩家的手牌、抓牌和牌搭,抓牌就一张牌,这个不需要考虑。手牌最多13张牌,没有间隙,显示布局如下:
牌牌牌牌牌牌牌牌牌牌牌牌牌
牌搭最多可以有4副(每副3张牌),而且牌搭之间需要有间隙(这里指定间隙为半张牌的宽度),布局如下:
牌牌牌 牌牌牌 牌牌牌 牌牌牌
所以牌搭所需的绘制面积最大(共计需要15张牌),其次是手牌(13张牌),抓牌和手牌可以一起(间隙一张牌),这样每个玩家需要绘制30张麻将牌的区域,准确的说应该是15 x 2张麻将牌,布局如下:
牌牌牌 牌牌牌 牌牌牌 牌牌牌
牌牌牌牌牌牌牌牌牌牌牌牌牌 牌
麻将桌的布局如下:
玩家2
玩 玩
家 家
3 1
玩家0
所以牌桌的边长应该为麻将牌宽度 x 15,加上麻将牌高度 x 4,如果选用40号麻将牌,则牌桌边长为30 x 15 + 40 x 4 = 610
更多内容请联系作者。
发自「今日水木 on iOS」
--
修改:cwall FROM 101.30.16.*
FROM 101.30.16.*
