雲原生項目實踐DevOps(GitOps)+K8S+BPF+SRE,從0到1使用Golang開發生產級麻將遊戲服務器—第8篇

麻將牌 (Mahjong tiles) 抽象和編碼實戰

一句話描述麻將遊戲業務:git

  • 三人模式<三人兩房>只用 子和 子兩種花色共 72 張牌。
  • 四人模式<血戰到底>使用 三種花色共 108 張牌。

系列文章

  1. Golang開發生產級麻將遊戲服務器—第1篇
  2. Golang開發生產級麻將遊戲服務器—第2篇
  3. Golang開發生產級麻將遊戲服務器—第3篇
  4. Golang開發生產級麻將遊戲服務器—第4篇
  5. Golang開發生產級麻將遊戲服務器—第5篇
  6. Golang開發生產級麻將遊戲服務器—第6篇
  7. Golang開發生產級麻將遊戲服務器—第7篇

介紹

這將是一個完整的,徹底踐行 DevOps/GitOpsKubernetes 上雲流程的 Golang 遊戲服務器開發的系列教程。github

這個系列教程是對開源項目 Nanoserver 的完整拆解,旨在幫助你們快速上手 Golang(遊戲)服務器後端開發。經過實踐去理解 Golang 開發的精髓 —— Share memory by communication(經過通訊共享內存)後端

同時這個項目可能還會涉及到 Linux 性能調優(BPF 相關的工具)和系統保障(SRE)的相關的工做。服務器

Step-By-Step 開發 Mahjong Server

  • 單體架構理解 Mahjong Server 業務 -> Nano Distributed Game Server(分佈式) + 微服務 改造。
  • Demo:go-mahjong-server

牌(Tiles)抽象

定義 Tile struct

type Tile struct {
	Id    int
	Suit  int
	Rank  int
	Index int
}
複製代碼
  • Id108 張牌,用 0~107 標識每一張牌。
  • Suit:三種花色,用 0~2 標識每一種花色(0:,1:,2:)。
  • Rank9 種點數,用 1~9 標識(如:1條,9條,1筒,9筒,1萬,9萬等…)。
  • Index:索引(條:1~9,筒:11~19,萬:21~29)。

經過一張表來理解

三種花色,每種類型牌的索引(Index):微信

條(1 ~ 9) 筒(11 ~ 19) 萬(21 ~ 29)
1 1條 11 1筒 21 1萬
2 2條 12 2筒 22 2萬
3 3條 13 3筒 23 3萬
4 4條 14 4筒 24 4萬
5 5條 15 5筒 25 5萬
6 6條 16 6筒 26 6萬
7 7條 17 7筒 27 7萬
8 8條 18 8筒 28 8萬
9 9條 19 9筒 29 9萬

全部牌(這裏是 108 張)的 ID 編號:markdown

條(0 ~ 35) 筒(36 ~ 71) 萬(72 ~ 107)
0 1條 36 1筒 72 1萬
1 1條 37 1筒 73 1萬
2 1條 38 1筒 74 1萬
3 1條 39 1筒 75 1萬
4 2條 40 2筒 76 2萬
5 2條 41 2筒 77 2萬
6 2條 42 2筒 78 2萬
7 2條 43 2筒 79 2萬
8 3條 44 3筒 80 3萬
9 3條 45 3筒 81 3萬
10 3條 46 3筒 82 3萬
11 3條 47 3筒 83 3萬
12 4條 48 4筒 84 4萬
13 4條 49 4筒 85 4萬
14 4條 50 4筒 86 4萬
15 4條 51 4筒 87 4萬
16 5條 52 5筒 88 5萬
17 5條 53 5筒 89 5萬
18 5條 54 5筒 90 5萬
19 5條 55 5筒 91 5萬
20 6條 56 6筒 92 6萬
21 6條 57 6筒 93 6萬
22 6條 58 6筒 94 6萬
23 6條 59 6筒 95 6萬
24 7條 60 7筒 96 7萬
25 7條 61 7筒 97 7萬
26 7條 62 7筒 98 7萬
27 7條 63 7筒 99 7萬
28 8條 64 8筒 100 8萬
29 8條 65 8筒 101 8萬
30 8條 66 8筒 102 8萬
31 8條 67 8筒 103 8萬
32 9條 68 9筒 104 9萬
33 9條 69 9筒 105 9萬
34 9條 70 9筒 106 9萬
35 9條 71 9筒 107 9萬

編碼實戰

經過 ID 獲取 Tile

一個算術問題,沒啥好說的。架構

  • 三種花色,每種有 9 類不一樣的牌,每類又有 4 張相同的牌。

internal/game/tile.go分佈式

func TileFromID(id int) *Tile {
	if id < 0 {
		panic("illegal tile id")
	}
	var (
		tmp = id / 4
		h   = tmp / 9
		v   = tmp%9 + 1
		i   = h*10 + v
	)
	return &Tile{Suit: h, Rank: v, Index: i, Id: id}
}
複製代碼

編寫單元測試函數

TileFromID 函數上右擊選擇 Generate Unit Tests For Function,咱們編寫它的單元測試函數。函數

internal/game/tile_test.go微服務

func TestTileFromID(t *testing.T) {
	type args struct {
		id int
	}
	tests := []struct {
		name string
		args args
		want *Tile
	}{
    // 定義一堆用例
		{"1條", args{id: 0}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 0}},
		{"1條", args{id: 1}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 1}},
		{"1條", args{id: 2}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 2}},
		{"1條", args{id: 3}, &Tile{Suit: 0, Rank: 1, Index: 1, Id: 3}},
		{"9條", args{id: 35}, &Tile{Suit: 0, Rank: 9, Index: 9, Id: 35}},
		{"1筒", args{id: 36}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 36}},
		{"1筒", args{id: 37}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 37}},
		{"1筒", args{id: 38}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 38}},
		{"1筒", args{id: 39}, &Tile{Suit: 1, Rank: 1, Index: 11, Id: 39}},
		{"9筒", args{id: 71}, &Tile{Suit: 1, Rank: 9, Index: 19, Id: 71}},
		{"1萬", args{id: 72}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 72}},
		{"1萬", args{id: 73}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 73}},
		{"1萬", args{id: 74}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 74}},
		{"1萬", args{id: 75}, &Tile{Suit: 2, Rank: 1, Index: 21, Id: 75}},
		{"9萬", args{id: 107}, &Tile{Suit: 2, Rank: 9, Index: 29, Id: 107}},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := TileFromID(tt.args.id); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("TileFromID() = %v, want %v", got, tt.want)
			}
		})
	}
}
複製代碼

執行:

cd internal/game/mahjong 
go test -v tile_test.go tile.go mahjong.go
複製代碼

我是爲少
微信:uuhells123
公衆號:黑客下午茶
加我微信(互相學習交流),關注公衆號(獲取更多學習資料~)
複製代碼
相關文章
相關標籤/搜索