cocos2dx 制作单机麻将(一)

今天開始打算解说下cocos2dx下怎样制作国标麻将

前半部分先解说麻将的逻辑部分,由于都是代码,可能会比較枯燥无聊. 这部分讲完后,你也能够用其它游戏引擎来制作麻将

后半部分,就解说余下的cocos2dx部分, 由于要把这部分留到后面讲,主要是还在考虑用3d做还是用2d做.

到最后能够扩展AI部分的机器人 和 server模块

麻将逻辑1. 打乱麻将顺序(初始化牌堆)

国标麻将共同拥有144张牌

#define MAX_REPERTORY 144

先把全部的牌放入一个常量数组中保存

每种牌都是1-9 共同拥有4张, 风牌就是东南西北,箭牌就是中发白,花牌就是春夏秋冬梅兰竹菊

const BYTE m_cbCardDataArray[MAX_REPERTORY]=

{

0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,//万子

0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,//万子

0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,//万子

0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,//万子

0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//同子

0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//同子

0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//同子

0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,//同子

0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,//索子

0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,//索子

0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,//索子

0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,//索子

0x31,0x32,0x33,0x34,//风牌

0x31,0x32,0x33,0x34,//风牌

0x31,0x32,0x33,0x34,//风牌

0x31,0x32,0x33,0x34,//风牌

0x41,0x42,0x43,//箭牌

0x41,0x42,0x43,//箭牌

0x41,0x42,0x43,//箭牌

0x41,0x42,0x43,//箭牌

0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,//花牌

};

有了顺序的数组,然后就能够打乱

打乱牌的函数

//混乱扑克

#define CountArray(Array) (sizeof(Array)/sizeof(Array[0]))

static void RandCardData(BYTE cbCardData[],BYTE cbMaxCount)

{

//混乱准备

BYTE cbCardDataTemp[CountArray(m_cbCardDataArray)];//为什么直接用MAX_REPERTORY?由于这样无耦合

memcpy(cbCardDataTemp,m_cbCardDataArray,sizeof(m_cbCardDataArray));//拷贝一份到暂时牌数组中

//混乱扑克(关键的核心打乱代码)

BYTE cbRandCount=0,cbPosition=0;

do

{

cbPosition=rand()%(cbMaxCount-cbRandCount);

cbCardData[cbRandCount++]=cbCardDataTemp[cbPosition];

cbCardDataTemp[cbPosition]=cbCardDataTemp[cbMaxCount-cbRandCount];

} while (cbRandCount<cbMaxCount);

return;

}

这样调用

BYTE _cardData[MAX_REPERTORY];

RandCardData(_cardData, MAX_REPERTORY);

以下是完整的控制台代码

//
//  main.cpp
//  MajiangLogicTest
//
//  Created by TinyUlt on 14-8-16.
//  Copyright (c) 2014年 TinyUlt. All rights reserved.
//

#include <iostream>
using namespace std;

#define MAX_REPERTORY 144
typedef unsigned char BYTE;

//数组维数
#ifndef CountArray
#define CountArray(Array) (sizeof(Array)/sizeof(Array[0]))
#endif
const BYTE m_cbCardDataArray[MAX_REPERTORY]=
{
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,						//万子
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,						//万子
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,						//万子
    0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,						//万子
    0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,						//同子
    0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,						//同子
    0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,						//同子
    0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,						//同子
    0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,						//索子
    0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,						//索子
    0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,						//索子
    0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,						//索子

    0x31,0x32,0x33,0x34,												//风牌
    0x31,0x32,0x33,0x34,												//风牌
    0x31,0x32,0x33,0x34,												//风牌
    0x31,0x32,0x33,0x34,												//风牌
    0x41,0x42,0x43,														//箭牌
    0x41,0x42,0x43,														//箭牌
    0x41,0x42,0x43,														//箭牌
    0x41,0x42,0x43,														//箭牌

    0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,							//花牌

};
//混乱扑克
static void RandCardData(BYTE cbCardData[],BYTE cbMaxCount)
{
    //混乱准备
    BYTE cbCardDataTemp[CountArray(m_cbCardDataArray)];//为什么不直接用MAX_REPERTORY? 由于这样无耦合
    memcpy(cbCardDataTemp,m_cbCardDataArray,sizeof(m_cbCardDataArray));//拷贝一份到暂时牌数组中

    //混乱扑克(关键的核心打乱代码)
    BYTE cbRandCount=0,cbPosition=0;
    do
    {
        cbPosition=rand()%(cbMaxCount-cbRandCount);
        cbCardData[cbRandCount++]=cbCardDataTemp[cbPosition];
        cbCardDataTemp[cbPosition]=cbCardDataTemp[cbMaxCount-cbRandCount];
    } while (cbRandCount<cbMaxCount);

    return;

}

int main(int argc, const char * argv[]) {
    // insert code here...

    BYTE _cardData[MAX_REPERTORY];

    RandCardData(_cardData, MAX_REPERTORY);

    for (int i = 0 ; i < MAX_REPERTORY; i++) {
        cout<<hex<<int(_cardData[i])<<" ";
    }

    return 0;
}

输出:

25 13 1 3 21 43 54 14 9 12 13 8 31 24 13 31 6 4 28 31 34 18 7 27 15 18 51 11 42 12 28 2 57 25 16 4 33 15 18 21 42 33 29 41 25 3 23 55 14 41 27 22 34 21 2 9 29 19 43 23 22 22 19 34 16 15 32 58 6 28 17 21 18 8 43 28 33 32 6 33 2 25 14 11 29 19 26 13 4 24 53 52
16 15 27 3 27 31 9 1 26 22 3 32 17 26 26 7 12 42 41 32 17 8 7 9 34 8 7 16 17 41 19 5 29 2 23 6 4 24 42 24 1 56 11 1 12 5 23 11 14 43 5 5
Program ended with exit code: 0

时间: 2024-10-11 06:55:28

cocos2dx 制作单机麻将(一)的相关文章

cocos2dx 制作单机麻将(六)

当项目做到这时, 会发现项目结构不是太美. 如果接着按照这样面向结构的方式写的话, 就会非常的乱. 这章我们来讨论如何用面向对象的方式写麻将. 标准的麻将(联网的) 会分为服务器模块, 客户端模块, 逻辑模块. 服务器模块必须由逻辑模块支持, 客户端模块很少用到逻辑模块,大多是从服务器发来的判断结果,必要时还是会用到逻辑模块. 因为逻辑模块需要共用, 所以里面都是调用的接口,返回服务器和客户端需要的结果值. 举个例子 客户端触发开始发生给服务端 > 服务端开始游戏 > 通过逻辑模块得到整理好的

cocos2dx 制作单机麻将(二)

麻将逻辑2. 打乱麻将顺序2 前面讲解了如何打乱初始给定的麻将牌堆, 还有一种是打乱任意给定的麻将牌堆 //混乱扑克2 void RandAppointCardData(BYTE cbCardData[],BYTE cbMaxCount,BYTE OriginalData[]/*源牌堆数据*/) { //混乱扑克 BYTE cbRandCount=0,cbPosition=0; do { cbPosition=rand()%(cbMaxCount-cbRandCount); cbCardData

cocos2dx 制作单机麻将(三)

麻将逻辑4.得到手牌数据 我们已经保存了一个一维数组, 类似于一个表格,统计出所有牌对应的数量, 但我们怎样得到当前手中是什么牌呢 //扑克转换 BYTE SwitchToCardData(BYTE cbCardIndex[MAX_INDEX]/*传入统计所有牌数量的表格*/, BYTE cbCardData[MAX_COUNT]/*传出手牌数据*/) { //转换扑克 BYTE cbPosition=0; for (BYTE i=0;i<MAX_INDEX;i++) { if (cbCardI

cocos2dx 制作单机麻将(五)

麻将逻辑6 最基础的4人麻将逻辑(轮流循环出牌, 之前学的都能用上  跑起来了!!!) 最基础的麻将逻辑 依据自己须要 设置麻将人数GAME_PLAYER 基本流程: 初始化牌堆, 推断庄家 玩家0摸13张牌 玩家1摸13张牌 玩家2摸13张牌 玩家3摸13张牌 庄家摸一张牌 庄家出牌 闲家摸牌 闲家出牌 闲家摸牌 闲家出牌 闲家摸牌 闲家出牌 庄家摸一张牌 庄家出牌 闲家摸牌 闲家出牌 ....... 牌堆数为0 结束 其它功能 比方 碰吃杠听胡等等 先不实现 代码不难,非常easy看懂 //

cocos2dx 制作单机麻将(四)

麻将逻辑5.模拟出牌 // // main.cpp // MajiangLogicTest // // Created by TinyUlt on 14-8-16. // Copyright (c) 2014年 TinyUlt. All rights reserved. // #include <iostream> using namespace std; #define MAX_REPERTORY 144 typedef unsigned char BYTE; typedef unsigne

【cocos2d-x制作别踩白块儿】第九期:游戏计时功能(附源代码)

游戏没有计时,不是坑爹吗? 这一期,我们将来加入游戏计时功能. 1. 定义变量和函数 我们先在HelloWorldScene.h中定义几个变量和函数 long startTime; bool timeRunning; startTime用来记录開始的时间,timeRunning用来推断游戏是否在进行中. //開始计时 void startTimer(); //结束计时 void stopTimer(); virtual void update(float dt); startTimer()函数时

Cocos2dx制作2048(3.数字相加逻辑)

这次我们来完成整个2048的数字相加逻辑其实2048玩起来简单,做起来也简单,复杂就复杂在这整个游戏的逻辑. 1.分析向左滑动 第一轮相加步骤: 1. 单1+单2    单1=2  单2赋值为0         (单1为空,可以加任何数字) 2. 单1+单3    单1=4   单3赋值为0    (单1不为空,只能加和他相同的数字) 3. 单1+单4    单1=4   单4不变              (单1不为空,只能加和他相同的数字) 第二轮相加步骤: 1.   单2+单3    单2

使用cocos2d-x制作 Texture unpacker

使用cocos2d-x制作 Texture unpacker 没错,就是unpacker. 在大多数游戏包里面,可以找到很多纹理图集,他们基本上是用texture packer制作的,有plist文件和png图片组成. 如果原来的小图比较少,倒是可以自己在plist里面找名字,如果小图有几百张,那真的会找疯掉.所以今天就用cocos2d-x引擎制作了一个将纹理大图解包成一张张小图的工具. 1. 解析plist文件 cocos2d-x引擎中实现了解析plist纹理的逻辑,SpriteFrameCa

cocos2dx《单机斗地主》源码解剖之八 电脑玩家出牌与跟牌(结束)

上一篇文章对玩家手中的牌进行分析归类,下面就该实现电脑玩家出牌与跟牌的策略了.首先我们来看看出牌的策略,代码如下: void GameScene::update(float delta){ switch (m_iState) { case 0: SendPk(); break; case 1: schedule(schedule_selector(GameScene::Call),1); break; case 2: scheduleOnce(schedule_selector(GameScen