go游戏后端开发26:红中麻将发牌逻辑

首先,麻将游戏创建房间的逻辑与之前我们做过的"赢三张"创建房间的逻辑是一致的,整体上没有问题。不同之处在于,我们在创建房间时会根据游戏类型来创建对应的"game",即创建的是麻将的"game"。大家之前写过相关代码,应该还有印象。

创建房间时,我们会传递一些规则,而这些规则会因游戏类型的不同而有所变化。例如,之前我们创建"赢三张"房间时,规则是这样的;而创建红中麻将房间时,规则又有所不同。因此,我们需要在原有规则的基础上添加一些新的规则,以适应麻将游戏的特性。至于房间号推送、游戏类型推送以及获取房间场景通知等功能,我们之前都已实现过。

唯一不同的是,在推送房间场景时,推送的内容会根据游戏类型而有所差异。对于麻将游戏,我们在推送游戏数据时,会包含一些麻将相关的游戏数据。接下来,我们就来完善这一部分的逻辑。

此外,还有游戏模式的选择,例如是4个红中还是8个红中;扎马的设置,包括2个、4个、6个、8个扎马或一马;最大人数、最小人数、房费、支付方式等。还有关于7队的规则,我们在讲解胡牌时提到过,7队是一种特殊的胡牌方式,大家可以根据需要选择是否允许7队的胡法。

还有一些规则,如语音功能、托管时长等。根据红中麻将的特点,我们整理了这些规则,并将其添加到规则设置中。因为有些规则是通用的,有些则是特定于麻将游戏的。在创建房间时,我们可以根据不同的规则加载相应的参数。

完成规则设置后,我们在创建房间时就可以加载这些规则了。接下来,我们还需要处理房间场景的推送,包括获取常见房间通知及对应的推送。依据之前的逻辑,我们需要在相应位置创建一个麻将目录,并在其中创建"game"和"type"。创建内容时,我们可以参考之前的模板,并确保所有必要的字段都已包含。

此外,我们还需要添加一些逻辑相关的代码,以及一些属性内容。例如,庄家信息、玩家人数、当前局数、游戏状态、是否已开始、倒计时、最大局数、玩家托管信息、手牌以及玩家操作等。每个玩家的操作可以包括胡牌、碰牌、吃牌、杠牌等,我们在代码中会将这些操作记录下来,并在需要时展示给玩家。

在游戏数据方面,我们已经准备好了相关定义,并可以直接将其复制到代码中。游戏数据还包括操作记录、剩余牌数、结算相关内容等。操作类型包括吃胡、自摸、碰、吃、杠、补杠、自摸杠、呼、气以及拿牌等。游戏状态则包括制筛子、发牌、游戏进行中、打牌或切磋等状态。

在处理游戏数据时,我们需要根据不同的游戏状态设置相应的时间限制,例如在操作时给予玩家30秒的操作时间。我们还需要在规则中设置一些参数,如翻倍规则等。

接下来,我们需要将游戏数据复制到相应的位置,并在房间创建时进行初始化。例如,根据规则设置玩家人数,麻将游戏需要至少两人、三人或四人到齐才能开始。我们还需要初始化手牌、操作状态、操作地图等数据,并将初始状态设置为等待状态。

在推送场景数据时,我们需要确保玩家只能看到自己的手牌,而看不到其他玩家的牌。为此,我们将其他玩家的牌设置为36,表示空牌或翻过来的牌。这样,前端在接收到数据后,就可以正确地显示牌的状态。

完成这些操作后,我们就可以进行初步测试了。重新启动应用,创建房间并加载房间数据,检查游戏数据是否正确推送。在测试过程中,我们发现了一些问题,例如在判断是否开始游戏时,需要根据游戏类型和玩家人数进行准确判断。我们对代码进行了调整,确保在满足条件时能够正确触发开始游戏的操作。

在开始游戏时,我们需要进行一系列的推送操作,包括游戏状态推送、庄家推送、摇骰子推送、发牌推送、剩余牌数推送、局数推送等。在发牌时,我们需要先进行洗牌操作,然后根据规则给每个玩家发13张牌,并将其他玩家的牌设置为不可见。在推送数据时,我们需要根据玩家的座次和UID进行针对性的推送。

完成这些操作后,游戏就可以正式开始了。玩家将进入拿牌阶段,我们可以为玩家设置一个短暂的操作时间,以便他们进行下一步的操作。在后续的游戏中,我们将继续完善玩家的操作逻辑,包括胡牌、碰牌、吃牌等操作的判断和处理。

复制代码
type CardID int

type CardIDs []CardID

func (c CardIDs) Len() int {
	return len(c)
}
func (c CardIDs) Less(i, j int) bool {
	return c[i] < c[j]
}
func (c CardIDs) Swap(i, j int) {
	c[i], c[j] = c[j], c[i]
}

const (
	Wan1  CardID = 1
	Wan2  CardID = 2
	Wan3  CardID = 3
	Wan4  CardID = 4
	Wan5  CardID = 5
	Wan6  CardID = 6
	Wan7  CardID = 7
	Wan8  CardID = 8
	Wan9  CardID = 9
	Tong1 CardID = 11
	Tong2 CardID = 12
	Tong3 CardID = 13
	Tong4 CardID = 14
	Tong5 CardID = 15
	Tong6 CardID = 16
	Tong7 CardID = 17
	Tong8 CardID = 18
	Tong9 CardID = 19
	Tiao1 CardID = 21
	Tiao2 CardID = 22
	Tiao3 CardID = 23
	Tiao4 CardID = 24
	Tiao5 CardID = 25
	Tiao6 CardID = 26
	Tiao7 CardID = 27
	Tiao8 CardID = 28
	Tiao9 CardID = 29
	Dong  CardID = 31
	Nan   CardID = 32
	Xi    CardID = 33
	Bei   CardID = 34
	Zhong CardID = 35
)

type Logic struct {
	sync.RWMutex
	cards    []CardID //12*9 + 4/8
	gameType GameType
	qidui    bool
	huLogic  *alg.HuLogic
}

func NewLogic(gameType GameType, qidui bool) *Logic {
	return &Logic{
		gameType: gameType,
		qidui:    qidui,
		huLogic:  alg.NewHuLogic(),
	}
}

func (l *Logic) washCards() {
	l.Lock()
	defer l.Unlock()
	l.cards = []CardID{
		Tong1, Tong2, Tong3, Tong4, Tong5, Tong6, Tong7, Tong8, Tong9,
		Tong1, Tong2, Tong3, Tong4, Tong5, Tong6, Tong7, Tong8, Tong9,
		Tong1, Tong2, Tong3, Tong4, Tong5, Tong6, Tong7, Tong8, Tong9,
		Tong1, Tong2, Tong3, Tong4, Tong5, Tong6, Tong7, Tong8, Tong9,
		Tiao1, Tiao2, Tiao3, Tiao4, Tiao5, Tiao6, Tiao7, Tiao8, Tiao9,
		Tiao1, Tiao2, Tiao3, Tiao4, Tiao5, Tiao6, Tiao7, Tiao8, Tiao9,
		Tiao1, Tiao2, Tiao3, Tiao4, Tiao5, Tiao6, Tiao7, Tiao8, Tiao9,
		Tiao1, Tiao2, Tiao3, Tiao4, Tiao5, Tiao6, Tiao7, Tiao8, Tiao9,
		Wan1, Wan2, Wan3, Wan4, Wan5, Wan6, Wan7, Wan8, Wan9,
		Wan1, Wan2, Wan3, Wan4, Wan5, Wan6, Wan7, Wan8, Wan9,
		Wan1, Wan2, Wan3, Wan4, Wan5, Wan6, Wan7, Wan8, Wan9,
		Wan1, Wan2, Wan3, Wan4, Wan5, Wan6, Wan7, Wan8, Wan9,
		Zhong, Zhong, Zhong, Zhong,
	}
	if l.gameType == HongZhong8 {
		l.cards = append(l.cards, Zhong, Zhong, Zhong, Zhong)
	}
	for i := 0; i < 300; i++ {
		index := i % len(l.cards)
		random := utils.Rand(len(l.cards))
		l.cards[index], l.cards[random] = l.cards[random], l.cards[index]
	}
}

func (l *Logic) getCards(num int) []CardID {
	l.Lock()
	defer l.Unlock()
	if len(l.cards) < num {
		return nil
	}
	cards := l.cards[:num]
	l.cards = l.cards[num:]
	return cards
}

func (l *Logic) getRestCardsCount() int {
	return len(l.cards)
}

func (l *Logic) getHongZhongCount(cards []CardID) int {
	count := 0
	for _, v := range cards {
		if v == Zhong {
			count++
		}
	}
	return count
}
相关推荐
范纹杉想快点毕业3 小时前
请创建一个视觉精美、交互流畅的进阶版贪吃蛇游戏
数据库·嵌入式硬件·算法·mongodb·游戏·fpga开发·交互
Buling_016 小时前
游戏中的设计模式——第三篇 简单工厂模式
游戏·设计模式·简单工厂模式
Jasmine_llq17 小时前
《P3825 [NOI2017] 游戏》
算法·游戏·枚举法·2-sat 算法·tarjan 算法·邻接表存储
小森程序员17 小时前
基于原神游戏物品系统小demo制作思路
游戏·原神·物品收集·物品消耗
宁檬精19 小时前
算法练习——55.跳跃游戏
数据结构·算法·游戏
wanhengidc21 小时前
高性价比云手机挑选指南
运维·网络·安全·游戏·智能手机
m0_552200821 天前
《UE5_C++多人TPS完整教程》学习笔记48 ——《P49 瞄准偏移(Aim Offset)》
c++·游戏·ue5
wanhengidc1 天前
云手机可以用来托管游戏吗?
运维·网络·安全·游戏·智能手机
伽蓝_游戏1 天前
UGUI源码剖析(15):Slider的运行时逻辑与编辑器实现
游戏·ui·unity·性能优化·c#·游戏引擎·.net
颯沓如流星2 天前
SLG游戏中沙盘元素(通常指资源点、野怪、宝箱等可交互对象)的刷新设计
游戏