xy hai 1 semana
pai
achega
1626590acd

+ 21 - 6
src/server/game/ludo/battle.go

@@ -181,6 +181,11 @@ func (room_info *RoomInfoWrapper) Get_cur_color_opt_time() int32 {
 func (room_info *RoomInfoWrapper) notify_player_sz() {
 	cur_color := room_info.CurRoundColor
 	room_info.StartCountdownPlayerOpt()
+	if room_info.containsRobot(cur_color) {
+		room_info.send_sz(cur_color)
+	} else {
+
+	}
 	message := &msg.NotifyPlayerOpt{
 		Color:   cur_color,
 		Opt:     msg.OptType_ZHI_SHAI_ZI,
@@ -242,10 +247,15 @@ func (room_info *RoomInfoWrapper) notify_to_all_player(message interface{}) {
 	for i := range room_info.Colors {
 		color_data := room_info.Colors[i]
 		user_id := color_data.MId
-		user_agent := getAgentByUserId(user_id)
-		if user_agent != nil && !color_data.IsKick {
-			user_agent.WriteMsg(message)
+		if room_info.containsRobot(color_data.MColor) {
+
+		} else {
+			user_agent := getAgentByUserId(user_id)
+			if user_agent != nil && !color_data.IsKick {
+				user_agent.WriteMsg(message)
+			}
 		}
+
 	}
 }
 
@@ -254,10 +264,15 @@ func (room_info *RoomInfoWrapper) notify_all_player(message interface{}) {
 	for i := range room_info.Colors {
 		color_data := room_info.Colors[i]
 		user_id := color_data.MId
-		user_agent := getAgentByUserId(user_id)
-		if user_agent != nil {
-			user_agent.WriteMsg(message)
+		if room_info.containsRobot(color_data.MColor) {
+
+		} else {
+			user_agent := getAgentByUserId(user_id)
+			if user_agent != nil {
+				user_agent.WriteMsg(message)
+			}
 		}
+
 	}
 }
 

+ 28 - 0
src/server/game/ludo/battle_manager.go

@@ -2,6 +2,7 @@ package ludo
 
 import (
 	"crypto/rand"
+	"fmt"
 	"math/big"
 	"server/msg"
 )
@@ -34,3 +35,30 @@ func getRandomItem[T any](slice []T) T {
 	n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(slice))))
 	return slice[n.Int64()]
 }
+
+// 随机获取一个人机名字
+func getRandomRobotName() string {
+	n, err := rand.Int(rand.Reader, big.NewInt(100))
+	if err != nil {
+		panic(err) // 在实际应用中应该更优雅地处理错误
+	}
+	return fmt.Sprintf("robot_%d", n)
+}
+
+// 随机获取一个人机头像
+func getRandomRobotHead() string {
+	n, err := rand.Int(rand.Reader, big.NewInt(13))
+	if err != nil {
+		panic(err) // 在实际应用中应该更优雅地处理错误
+	}
+	return fmt.Sprintf("3_%d", n)
+}
+
+// 随机获取一个人机金币
+func getRandomRobotCoin() int32 {
+	n, err := rand.Int(rand.Reader, big.NewInt(1000))
+	if err != nil {
+		panic(err) // 在实际应用中应该更优雅地处理错误
+	}
+	return int32(n.Int64()) + 1000
+}

+ 1 - 0
src/server/game/ludo/ludo.go

@@ -132,6 +132,7 @@ func InitGame() {
 		BattleRoom: make(map[int32]*RoomInfoWrapper),
 	}
 	go handleEvents()
+	go StartMatchRobotTask()
 }
 
 func startGame(room_info *msg.RoomInfo) *RoomInfoWrapper {

+ 91 - 0
src/server/game/ludo/match_robot.go

@@ -0,0 +1,91 @@
+package ludo
+
+import (
+	"fmt"
+	"server/msg"
+	"time"
+)
+
+var wait_room map[int32]time.Time
+
+var namesArray [10]string = [10]string{
+	"Alice", "Bob", "Charlie", "David", "Eve",
+	"Frank", "Grace", "Henry", "Ivy", "Jack",
+}
+
+func AddWaitRoomList(room_id int32) {
+	wait_room[room_id] = time.Now()
+}
+
+func RemoveWaitRoomList(room_id int32) {
+	delete(wait_room, room_id)
+}
+
+func StartMatchRobotTask() {
+	// 创建每秒触发一次的定时器
+	ticker := time.NewTicker(1 * time.Second)
+	defer ticker.Stop() // 确保退出时释放资源
+
+	for {
+		select {
+		case <-ticker.C:
+			Scheduling()
+		}
+	}
+}
+
+func Scheduling() {
+
+	for room_id, start_time := range wait_room {
+		room_info := gameConfig.RoomMap[room_id]
+		if room_info == nil {
+			RemoveWaitRoomList(room_id)
+		} else {
+			if room_info.RoomStatus != msg.RoomStatus_AWAIT {
+				RemoveWaitRoomList(room_id)
+			} else {
+				cur_time := time.Now()
+				// 计算整数秒(直接截断小数部分)
+				seconds := int(cur_time.Sub(start_time).Seconds())
+
+				if seconds > 5 { //5秒还没匹配完成就给玩家匹配机器人
+					room_info.RoomStatus = msg.RoomStatus_START
+					lack_num := 0
+					if room_info.RoomType == msg.RoomType_SHUANG_REN {
+						lack_num = 2 - len(room_info.Colors)
+					} else {
+						lack_num = 4 - len(room_info.Colors)
+					}
+					addRobot(room_info, lack_num)
+				}
+			}
+		}
+	}
+}
+
+func addRobot(room_info *msg.RoomInfo, num int) {
+	for i := 0; i < num; i++ {
+		matchInfo := &msg.MatchLudo{}
+		robot_user_id := fmt.Sprintf("robot_%d", i)
+		isFullPlayer, err_info := JoinRoom(room_info, matchInfo, robot_user_id)
+		if err_info == nil {
+			if isFullPlayer {
+				start_room := startGame(room_info)
+				fmt.Printf("%v:匹配成功开始游戏!", start_room)
+				NotifyRoomPlayerMatch(start_room)
+			}
+		}
+	}
+
+}
+
+func getNewRobotPlayer(userId string, room_id int32) (*msg.UserInfo, error) {
+	robot_player := &msg.UserInfo{
+		UserId: userId,
+		MCoin:  getRandomRobotCoin(),
+		MHead:  getRandomRobotHead(),
+		Name:   getRandomRobotName(),
+		RoomId: room_id,
+	}
+	return robot_player, nil
+}

+ 23 - 11
src/server/game/ludo/room.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	redismgr "server/db/redis"
 	"server/msg"
+	"strings"
 )
 
 // 判断是否已存在选择的阵营
@@ -75,7 +76,7 @@ func CreateRoom(matchInfo *msg.MatchLudo, userId string) (*msg.RoomInfo, error)
 	}
 	// 生成房间ID(不加锁)
 	roomId := generateRoomID()
-
+	AddWaitRoomList(roomId)
 	newRoom := &msg.RoomInfo{
 		Id:         roomId,
 		RoomLevel:  int32(matchInfo.RoomLevel),
@@ -114,7 +115,16 @@ func CreateRoom(matchInfo *msg.MatchLudo, userId string) (*msg.RoomInfo, error)
 }
 
 func JoinRoom(room *msg.RoomInfo, matchInfo *msg.MatchLudo, userId string) (bool, error) {
-	userInfo, err_info := redismgr.GetUserInfoFromRedis(userId)
+
+	isRobot := strings.Contains(userId, "robot")
+	var userInfo *msg.UserInfo = nil
+	var err_info error = nil
+	if isRobot {
+		userInfo, err_info = getNewRobotPlayer(userId, room.Id)
+	} else {
+		userInfo, err_info = redismgr.GetUserInfoFromRedis(userId)
+	}
+
 	if err_info != nil {
 		return false, errors.New("not find user at JoinRoom time ")
 	}
@@ -135,17 +145,19 @@ func JoinRoom(room *msg.RoomInfo, matchInfo *msg.MatchLudo, userId string) (bool
 		MCoin:      userInfo.MCoin,        //玩家拥有的金币
 	})
 
-	ud := &msg.UserInfo{
-		UserId: userInfo.UserId,
-		Name:   userInfo.Name,
-		MCoin:  userInfo.MCoin,
-		MHead:  userInfo.MHead,
-		RoomId: room.Id,
-	}
+	if !isRobot {
+		ud := &msg.UserInfo{
+			UserId: userInfo.UserId,
+			Name:   userInfo.Name,
+			MCoin:  userInfo.MCoin,
+			MHead:  userInfo.MHead,
+			RoomId: room.Id,
+		}
 
-	redismgr.SaveUserInfoToRedis(ud)
+		redismgr.SaveUserInfoToRedis(ud)
 
-	user_agent.SetUserData(ud)
+		user_agent.SetUserData(ud)
+	}
 
 	isFullPlayer := false