[網頁五子棋][匹配模式]創建房間類、房間管理器、驗證匹配功能,匹配模式小結

文章目錄

  • 創建房間類
    • 創建房間類
    • 實現房間管理器
  • 實現匹配器(3)
  • 驗證匹配功能
    • 問題:匹配按鈕不改變
    • 驗證多開
  • 小結

創建房間類

LOL,通過匹配的方式,自動給你加入到一個房間,也可手動創建游戲房間

  • 這一局游戲,進行的“場所”就可以稱為是一個“游戲房間”,游戲房間中最關鍵的信息,就是玩家信息
  • 一個游戲服務器,有同時存在了多個游戲房間

我們就需要一個“游戲房間管理器”來管理多個游戲房間image.png|429

  • 鍵值對的方式,給每個 room 生成一個唯一的 roomId,以鍵值對 (哈希表) 在 room manager 中來進行管理

創建房間類

匹配成功之后,需要把對戰的兩個玩家放到同一個房間對象中

創建 game.Room

  • 一個房間要包含一個房間 ID,使用 UUID 做為房間的唯一身份標識
  • 房間內要記錄對弈的玩家雙方信息

UUID 表示“世界上唯一的身份標識”

  • 通過一系列的算法,能夠生成一串字符串(一組十六進制表示的數字)
  • 兩次/任意次調用這個算法,生產的這個字符串都是不同的
package org.example.java_gobang.game;  import org.example.java_gobang.model.User;  import java.util.UUID;  // 表示一個游戲房間  
public class Room {  // 此處我們使用字符串的類型來表示,方便生成唯一值  private String roomId;  private User user1;  private User user2;  public String getRoomId() {  return roomId;  }  public void setRoomId(String roomId) {  this.roomId = roomId;  }  public User getUser1() {  return user1;  }  public void setUser1(User user1) {  this.user1 = user1;  }  public User getUser2() {  return user2;  }  public void setUser2(User user2) {  this.user2 = user2;  }  public Room() {  // 構造 Room 的時候,生成一個唯一的字符串來表示房間 id        roomId = UUID.randomUUID().toString();  }  
}

實現房間管理器

Room 對象會存在很多,每兩個對弈的玩家,都對應一個 Room 對象,需要創建一個管理器對象來管理所有的 Room

創建 game.RoomManager

  • 使用一個 Hash 表,保存所有房間對象
    • key:roomId
    • value:Room對象
  • 再使用一個 Hash 表,保存 userId -> RoomId 的映射,方便根據玩家來查找所在的房間
  • 提供增、刪、查的 API
    • 查詢包含基于房間 ID 的查詢和基于用戶 ID 的查詢
package org.example.java_gobang.game;  import org.springframework.stereotype.Component;  import java.util.concurrent.ConcurrentHashMap;  // 房間管理器,這個類也希望有唯一實例  
@Component  
public class RoomManager {  private ConcurrentHashMap<String, Room> rooms = new ConcurrentHashMap<>();  // 通過這個哈希表,把玩家和房間之間的關系維護起來  private ConcurrentHashMap<Integer, String> userIdToRoomId = new ConcurrentHashMap<>();  public void add(Room room, int userId1, int userId2) {  rooms.put(room.getRoomId(), room);  userIdToRoomId.put(userId1, room.getRoomId());  userIdToRoomId.put(userId2, room.getRoomId());  }  public void remove(String roomId, int userId1, int userId2) {  rooms.remove(roomId);  userIdToRoomId.remove(userId1);  userIdToRoomId.remove(userId2);  }  public Room getRoomByRoomId(String roomId) {  return rooms.get(roomId);  }  // 根據用戶id 定位房間  public Room getRoomByUserId(int userId) {  String roomId = userIdToRoomId.get(userId);  if(roomId == null) {  // userId -> roomId 映射關系不存在,直接返回 null            return null;  }  return rooms.get(roomId);  }  
}

實現匹配器(3)

完善剛才匹配邏輯中的 TODO,并把玩家放到一個房間中 image.png|353

  • 先給 Matcher 注入 RoomManager 對象
@Component
public class Matcher {//......// 房間管理器@Autowiredprivate RoomManager roomManager;// ......
}然后修改 Matcher.handlerMatch,補完之前 TODO 的內容
private void handlerMatch(Queue<User> matchQueue) {// 4. 把這兩個玩家放到一個游戲房間中  Room room = new Room();  roomManager.add(room, player1.getUserId(), player2.getUserId());// ......
}

驗證匹配功能

問題:匹配按鈕不改變

當前發現,玩家點擊匹配之后,匹配按鈕的文本不發生改變

  • 分析之前寫的代碼,點擊按鈕的時候,僅僅是給服務器發送了一個 websocket 請求,告訴服務器我要開始匹配了
  • 服務器會立即返回一個響應,“進入匹配隊列成功”,然后頁面再修改按鈕的文本image.png|372

出現問題的原因:

  • 服務器在處理匹配請求的時候,按理說是要立即就返回一個 websocket 響應的
  • 實際上在服務器代碼這里構造了響應對象,但是忘記 sendMessage,給發回去了image.png|338
    在紅框中加入如下邏輯代碼
// 將 response 先轉換成 JSON 字符串,然后將其通過 sendMessage 發回客戶端  
String jsonString = objectMapper.writeValueAsString(response);  
session.sendMessage(new TextMessage(jsonString));

就類似于:你網購買了個東西,商家都已經打包好了,但是最后忘記發貨了

image.png

驗證匹配功能的時候,模擬多個用戶登錄的情況,最好使用多個瀏覽器,避免同一個瀏覽器中的 cookie/session 信息互相干擾

  • 如果只有一個瀏覽器,并且是 chrome 的話,chrome 有個無痕模式(不會記錄歷史記錄,也不會記錄 cookie,頁面關閉的時候會自動清空)

驗證多開

當我們打開兩個頁面,登錄同一個賬號的時候,后登錄的頁面的檢查頁面會出現提示,但是正常用戶多開了在頁面中卻沒有顯示 image.png

  • 當用戶多開之后,連接就會直接關閉,不能再進行匹配了image.png
    image.png|449

當前情況下,防多開機制起到了作用,但是又感覺差了點意思

  • 要是在第二個賬號登錄的時候,在頁面中直接有提示就更好了

此時我們就可以調整前端代碼,當檢測到多開的時候,就給用戶一個更加明確的提示 image.png|422

這樣,在我們登錄的時候,要是出現了多開的情況,就直接報錯了,返回重新登錄頁面image.png|492

  • 當我們修改了 css 樣式/ JS 文件之后,往往要在瀏覽器中使用 cmd+shift+R(Windows:ctrl+f5)強制刷新,才能生效
  • 否則瀏覽器可能仍然在執行舊版本的代碼(瀏覽器自帶緩存)

小結

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85151.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Apifox 5 月產品更新|數據模型支持查看「引用資源」、調試 AI 接口可實時預覽 Markdown、性能優化

Apifox 新版本上線啦&#xff01; 看看本次版本更新主要涵蓋的重點內容&#xff0c;有沒有你所關注的功能特性&#xff1a; 自動解析 JSON 參數名和參數值調試 AI 接口時&#xff0c;可預覽 Markdown 格式的內容性能優化&#xff1a;新增「實驗性功能」選項 使用獨立進程執行…

Spring MVC 框架

目錄 1.MVC的定義 2.SpringMVC的實際應用 &#xff08;1&#xff09;建立連接 1.RequestMapping注解介紹 2.RequestMapping注解的請求方式 GET請求&#xff1a; POST請求&#xff1a; 指定GET/POST方法類型&#xff1a; &#xff08;2&#xff09;請求 傳遞參數 1.傳…

基于RK3568/RK3588/全志H3/飛騰芯片/音視頻通話程序/語音對講/視頻對講/實時性好/極低延遲

一、前言說明 近期收到幾個需求都是做音視頻通話&#xff0c;很多人會選擇用webrtc的方案&#xff0c;這個當然是個不錯的方案&#xff0c;但是依賴的東西太多&#xff0c;而且相關組件代碼量很大&#xff0c;開發難度大。所以最終選擇自己屬性的方案&#xff0c;那就是推流拉…

AI+爆款文案,提示詞腳本 ——衛朋

目錄 簡介 提示詞 作者簡介 簡介 用好AI的前提是腦子里面要有框架。 AI就像是一個剛出生的小孩&#xff0c;沒有判斷力&#xff0c;瘋狂接收世界上的各類信息。 如果沒有從小的規則框架約束、沒有道德約束&#xff0c;最終的結果就一定是混亂無序的。 AI也是一樣&#x…

芯片:數字時代的算力引擎——鯤鵬、升騰、海光、Intel 全景解析

在大模型爆炸的時代&#xff0c;芯片如同現代文明的“數字心臟”&#xff0c;驅動著從智能手機、數據中心到人工智能和超級計算的每一個關鍵進程。在這場算力競賽中&#xff0c;華為鯤鵬、升騰、海光以及行業巨頭Intel各自扮演著獨特而至關重要的角色。本文將深入解析這些核心算…

傳輸層協議TCP(上)

上一篇https://blog.csdn.net/Small_entreprene/article/details/148143494?fromshareblogdetail&sharetypeblogdetail&sharerId148143494&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link 上文學習了傳輸層的協議之一UDP&#xff0c;接下來…

關于ios點擊分享自動復制到粘貼板的問題

前言 Android 系統沒有什么特別的要求&#xff0c;實現這個也比較容易。但ios在某些情況下就會出現問題。 如果ios是點擊之后&#xff0c;請求接口&#xff0c;再把接口的內容賦值給粘貼板肯定行不通&#xff0c;會被ios系統攔截&#xff0c;導致賦值失敗或者賦值為空。建議使…

SAP Business One:無錫哲訊科技助力中小企業數字化轉型的智慧之選

數字化轉型&#xff0c;中小企業的必經之路 在當今競爭激烈的商業環境中&#xff0c;數字化轉型已不再是大型企業的專利&#xff0c;越來越多的中小企業開始尋求高效、靈活的管理系統來優化業務流程、提升運營效率。作為全球領先的企業管理軟件&#xff0c;SAP Business One…

【孫悟空喝水】2022-2-7

緣由C編程問題求解:9634: 孫悟空喝水-編程語言-CSDN問答 void 孫悟空喝水() {//緣由https://ask.csdn.net/questions/7639865?spm1005.2025.3001.5141int x 2&#xff0c; n 0; double s 0, ss 0;std::cin >> n;while ((int)s < n)s 1.0 / x, ss (x - 1.0) / …

OCC筆記:BRepMesh_IncrementalMesh的使用

1. 函數接口 2. 線性偏轉與角度偏轉 2.1. theLineDeflection&#xff1a;線性偏轉 根據文檔推導下 isRelative傳入Standard_True時&#xff0c;theLineDeflection為相對值。 參看isRelative說明 //! param isRelative if TRUE deflection used for discretization of //! ea…

Visual Studio+SQL Server數據挖掘

這里寫自定義目錄標題 工具準備安裝Visual studio 2017安裝SQL Server安裝SQL Server Management Studio安裝analysis service SSMS連接sql serverVisual studio新建項目數據源數據源視圖挖掘結構部署模型設置挖掘預測 部署易錯點 工具準備 Visual studio 2017 analysis servi…

如何遷移SOS數據庫和修改sos服務的端口號

一. 遷移SOS數據庫。 1. 對SOS整個庫進行拷貝。壓縮拷貝等都可以 2. 找到SOS安裝目錄下的這個目錄 /SOS7/SERVERS7/LOCAL/ 在此目錄下會發現&#xff0c;有SOS服務庫的文件夾。拷貝你要遷移的SOS數據庫 3. 進入該文件夾&#xff0c;找到&#xff1a;serverdb.cfg 打開后&…

Oracle向PG轉移建議以及注意點

Oracle向PG轉移建議以及注意點 ? 一、語法差異與遷移建議 1. 包結構&#xff08;Package&#xff09; Oracle 支持 PACKAGE 和 PACKAGE BODY 分離定義。PostgreSQL 不支持包結構&#xff0c;需將每個函數/過程單獨定義。 遷移建議&#xff1a; 將 PACKAGE 包中的每個函數…

PCIe-PCI、PCIe中斷機制概述

PCI、PCIe中斷概述 PCIe 中斷機制在繼承 PCI 傳統中斷&#xff08;INTx&#xff09;的基礎上&#xff0c;引入了更高效的 MSI/MSI-X 方案&#xff0c;以提升設備性能并減少 CPU 輪詢開銷。以下是核心要點及技術演進&#xff1a; ?? ??一、PCIe 中斷類型與演進?? ??IN…

改進自己的圖片 app

1. 起因&#xff0c; 目的: 前面我寫過一個圖片 app &#xff0c; 最新做了些改動。 把原來的一列&#xff0c;改為3列&#xff0c; 繼續使用瀑布流手機上使用&#xff0c;更流暢&#xff0c;橫屏顯示為2列。 2. 先看效果 3. 過程: 過程太細碎了&#xff0c;這里只是做一下…

【HTML-15】HTML表單:構建交互式網頁的基石

表單是HTML中最強大的功能之一&#xff0c;它允許網頁收集用戶輸入并與服務器進行交互。無論是簡單的搜索框、登錄頁面&#xff0c;還是復雜的多步驟調查問卷&#xff0c;表單都是實現這些功能的核心元素。本文將深入探討HTML表單的各個方面&#xff0c;幫助您構建高效、用戶友…

關于智能體接入后端,在Apifox能夠傳參數給智能體的測試

from flask import Flask, request, jsonify, render_template import requests import json # 用于解析嵌套的 JSON 字符串app Flask(__name__)COZE_BOT_ID 7508736911423963162 COZE_API_KEY pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws COZE…

SQL進階之旅 Day 8:窗口函數實用技巧

【SQL進階之旅 Day 8】窗口函數實用技巧 在現代數據庫開發中&#xff0c;處理復雜的業務邏輯和大規模數據時&#xff0c;僅僅依靠傳統的GROUP BY和JOIN操作已經無法滿足需求。**窗口函數&#xff08;Window Function&#xff09;**作為SQL標準的一部分&#xff0c;為開發者提供…

編譯rustdesk,使用flutter、hwcodec硬件編解碼

目錄 安裝相應的環境安裝visual studio安裝vpkg安裝rust開發環境安裝llvm和clang編譯源碼下載源碼使用Sciter作為UI的(已棄用)使用flutter作為UI的(主流)下載flutter sdk橋接靜默安裝最近某desk免費的限制越來越多,實在沒辦法,平時遠程控制用的比較多,只能用rustdesk了,…

由反匯編代碼確定結構體的完整聲明

C程序中遇到下面的代碼 typedef struct {int left;a_struct a[CNT];int right; } b_struct;void test( int i, b_struct *bp) {int nbp->leftbp->right;a_struct *ap&bp->a[i];ap->x[ap->idx]n; } 下面是test函數的反匯編代碼 結合C程序中的代碼與test函數…