Day7 配对条件范例 (角色,人数上限)

今天我们要自己假订一个配对情境,来做一个比官方稍微复杂一点点的 Demo,并且透过这个模拟情境的实践,来熟悉 Open-Match 在实作上须满足的接口与函式用法。

情境

随机产生两个地区、两种职业与不同等级条件的配对请求,并且将两个不同职业才能配对的逻辑,加入我们的配对逻辑中

部署范例

  • 移除官方 demo (若无部署可以跳过)

    kubectl delete namespaces open-match-demo
    
  • 下载本次范例用 yaml

    open-match/open-match-role-location-demo.yml at example-a.2 · WeiWeiWesley/open-match

    主要基於官方 yaml 替换掉 demo 与 mmf 的 images 为本次范例所需要的情境

    - name: om-demo
            image: "weiweiwesley/open-match:example-a.2"
    
    ...
    
    - name: om-function
            image: "weiweiwesley/mmf_role_location:diff_role.2"
    
    ...
    
  • 部署

    
    kubectl create namespace open-match-demo
    
    kubectl apply -n open-match-demo -f open-match-role-location-demo.yml
    

    https://i.imgur.com/HConrwO.png

主要异动

Client

以时间乱数产生不同的配对请求,分别将不同型态的条件放到 StringArgsDoubleArgs 内。实务上这些资料,更可能是由捞取使用者资料库获得。

var ticketId string
	{

		ticket := &pb.Ticket{}

		//随机产生不同条件
		//两个地区
		//两种职业
		//等级 0~30
		switch time.Now().Unix() % 4 {
		case 0:
			ticket.SearchFields = &pb.SearchFields{
				StringArgs: map[string]string{
					"location": "Asia/Taiwan",
					"role":     "knight",
				},
				DoubleArgs: map[string]float64{
					"level": float64(rand.Int31n(30)),
				},
			}
		case 1:
			ticket.SearchFields = &pb.SearchFields{
				StringArgs: map[string]string{
					"location": "Asia/Taiwan",
					"role":     "archer",
				},
				DoubleArgs: map[string]float64{
					"level": float64(rand.Int31n(30)),
				},
			}
		case 2:
			ticket.SearchFields = &pb.SearchFields{
				StringArgs: map[string]string{
					"location": "Asia/Japan",
					"role":     "knight",
				},
				DoubleArgs: map[string]float64{
					"level": float64(rand.Int31n(30)),
				},
			}
		case 3:
			ticket.SearchFields = &pb.SearchFields{
				StringArgs: map[string]string{
					"location": "Asia/Japan",
					"role":     "archer",
				},
				DoubleArgs: map[string]float64{
					"level": float64(rand.Int31n(30)),
				},
			}
		}

		req := &pb.CreateTicketRequest{Ticket: ticket}

		s.Status = fmt.Sprintf("Create ticket role: %s location: %s", ticket.SearchFields.StringArgs["role"], ticket.SearchFields.StringArgs["location"])
		update(s)
		time.Sleep(time.Second)

		resp, err := fe.CreateTicket(ctx, req)
		if err != nil {
			panic(err)
		}
		ticketId = resp.Id
	}

MMF

Match Function 是我们实作配对逻辑的部份,这边可以看到我们能针对 ticket.SearchFields 的内容,对请求是否进行同场配对做筛选 ,previousRole 在记录下玩家角色後,会拒绝配对相同角色的玩家。

func makeMatches(poolTickets map[string][]*pb.Ticket) ([]*pb.Match, error) {
	tickets := map[string]*pb.Ticket{}
	for _, pool := range poolTickets {
		for _, ticket := range pool {
			tickets[ticket.GetId()] = ticket
		}
	}

	var matches []*pb.Match

	t := time.Now().Format("2006-01-02T15:04:05.00")

	thisMatch := make([]*pb.Ticket, 0, 2)
	matchNum := 0

	previousRole := ""
	for _, ticket := range tickets {
		log.Println("pairing:", ticket.Id, ticket.SearchFields.StringArgs["role"])

		//若同职业则会跳过此次配对
		if previousRole != ticket.SearchFields.StringArgs["role"] {
			thisMatch = append(thisMatch, ticket)
			previousRole = ticket.SearchFields.StringArgs["role"]
		}

		if len(thisMatch) >= 2 {
			matches = append(matches, &pb.Match{
				MatchId:       fmt.Sprintf("profile-%s-time-%s-num-%d", matchName, t, matchNum),
				MatchProfile:  matchName,
				MatchFunction: matchName,
				Tickets:       thisMatch,
			})

			log.Println("pairing success", thisMatch[0].SearchFields.StringArgs["role"], thisMatch[1].SearchFields.StringArgs["role"])

			previousRole = ""
			thisMatch = make([]*pb.Ticket, 0, 2)
			matchNum++
		}
	}

	return matches, nil
}

快速抽换配对条件

基於 Open-Match 框架已经将 MMF 独立为一个服务实体启动,我们可以利用 kubernetes rolling update 的特性,动态的抽换线上的 MMF。我们可以试着将本篇范例的 MMF,再度更换为官方demo 的映像党,并重新 apply 上便可以再度恢复成任意两人即可配对成功。

更换 MMF

- name: om-function
        image: "gcr.io/open-match-public-images/openmatch-mmf-go-soloduel:1.2.0"

Just apply again

kubectl apply -n open-match-demo -f open-match-role-location-demo.yml

本日心得

单纯利用 tickets 的资料进行条件筛选,这在 client or MMF 实作上都是非常简易的,我们可以依照游戏的各种特性,以及玩家游玩过程与实体所产生的资料来产生不同的配对条件。本次范例中仅用两种不同角色即可配对,而那些没有配对到的玩家,会等到出现不同角色时才配对,这可能会发生一个尴尬的情况:如果大家都是选择相同角色时,所有人都会卡在配对等待中的状态。为了避免等待时间过长,之後一点的篇幅会再用一个范例来教大家如何释放 tickets。

此外由於本次范例是想沿用官方 demo 介面,直接从官方demo fork 出来异动,会有一些 golang 相依上的一些问题,这与 Open-Match 本身的使用上没有直接相关,所以为了让范例顺利已将 images 放在 dockerHub 上。


<<:  Day 01 - objective C 基础语法

>>:  [13th][Day7] container 处理程序

Day33 - Windows 提权(4)-常见提权脚本

列出常见的针对 Windows 提权的脚本 Windows Vista/7 – Elevation ...

sed - 4 Write commands

前篇回顾 sed - 简介 读取编辑文字档的好工具 sed - 2 Pattern sed - 3 ...

Day09 - 用 Cloud Run 部属 Serverless 容器应用

什麽是 Serverless ? 若要将应用程序部属到生产环境,会需要考虑很多问题,包括计算资源是否...

隐藏&显示画面中间的某区块

缘由: 开发时或多或少会遇到因某个条件地达成,需要显示或隐藏画面中的另一个条件,若是区块在最底部,直...

[Day 20] 机器学习金手指 - Auto-sklearn

Auto-sklearn 今日学习目标 了解 Auto-sklearn 运作原理 Meta Lear...