// 定义线程方法:等待人的叫分信息 private void waitPeopleCallScore(object msg) { try { //等待玩家叫分的时间,如果玩家在指定时间内没有叫分,认为玩家那方出现问题,设置玩家离线 ThreadMsg threadMsg = (ThreadMsg)msg; Thread.Sleep(threadMsg.waitTime); lobby.players[threadMsg.curPeople].setLeaveState(); //设置随机的叫分 CallScoreProcess.callScore(0, ref lobby.players[threadMsg.curPeople]); } catch (Exception e) { } }
//服务器进程更新 public void processUpdate() { //判断是不是心跳信息 if (JudgeOtherInfo.judgeHeartBeatMsg(msg) == true) { return; } //判断是否为玩家离开的消息 else if (JudgeOtherInfo.judgeLeaveMsg(msg) == true) { clientBreak(false); return; } switch (step) { //如果是登录状态(注册)(断线重连) case ServerProcess.LOGIN_PROCESS: { //登录验证阶段(分析登录是否成功,返回登录结果) LoginResult loginResult = LoginResult.NONE; bool isReconnected = false; string senderLogin = LoginProcess.startLogin(msg, ref loginResult, ref player, ref isReconnected); //向客户端发送登录是否成功 sendMessange(senderLogin); //如果登录成功(如果为断线重连状态,由player中的函数进行状态跳转) if (loginResult == LoginResult.LOGIN_SUCCESS) { //将已登录的用户存入到players中 serverForm.server.players.TryAdd(player.username, null); //将当前进程赋给玩家 player.curServerDeal = this; //下一步进入游戏大厅匹配环节 next_step = ServerProcess.MATCH_PROCESS; } else if (isReconnected) { //将当前进程赋给玩家 player.curServerDeal = this; //将自身接受的消息改为对应的状态 if (player.gameProcess.step == GameProcessEnum.CALL_SCORE) { next_step = ServerProcess.CALL_SCORE_PROCESS; } else if (player.gameProcess.step == GameProcessEnum.OUT_CARD) { next_step = ServerProcess.OUT_CARD_PROCESS; } } } break; //如果是游戏大厅匹配阶段(个人信息修改)(断线重连) case ServerProcess.MATCH_PROCESS: { bool isMatched = false; bool isReconnected = false; //创建匹配处理的进程 string matchResult = MatchProcess.startMatch(msg, ref player, out isMatched, ref isReconnected); //向客户端发送匹配结果(成功,返回当前房间的状态) sendMessange(matchResult); //如果匹配成功(进入房间)(如果为断线重连状态,由player中的函数进行状态跳转) if (isMatched == true) { next_step = ServerProcess.PREPARE_GAME_PROCESS; } else if (isReconnected) { //将当前进程赋给玩家 player.curServerDeal = this; //将自身接受的消息改为对应的状态 if (player.gameProcess.step == GameProcessEnum.CALL_SCORE) { next_step = ServerProcess.CALL_SCORE_PROCESS; } else if (player.gameProcess.step == GameProcessEnum.OUT_CARD) { next_step = ServerProcess.OUT_CARD_PROCESS; } } } break; //如果是游戏房间准备阶段 case ServerProcess.PREPARE_GAME_PROCESS: { //创建准备处理的进程 PrepareGameProcess.startPrepareGame(msg, ref player); //向客户端发送匹配结果 //sendMessange(prepareResult); } break; //游戏开始,接受叫分的信息(卡组信息已在GameProcess中发过) case ServerProcess.CALL_SCORE_PROCESS: { CallScoreProcess.receiveScoreMsg(msg, ref player); } break; //接受玩家的出牌信息(这局结束后由GameProcess进行步骤跳转,跳到PREPARE_GAME_PROCESS) case ServerProcess.OUT_CARD_PROCESS: { OutCardProcess.receiveOutCardMsg(msg, ref player); } break; } //改变状态前的初始化(跳入下一阶段) initProcessUpdate(); }
//游戏进程的更新 public void processUpdate() { switch (step) { //游戏开始 case GameProcessEnum.GAME_START: { //进入下一步的叫分环节 next_step = GameProcessEnum.CALL_SCORE; //四名玩家同时进入叫分阶段 for (int i = 0; i < 4; i++) { //如果该玩家不是机器人(离线的玩家也要对其状态进行更新) if (lobby.players[i].playerEnum != PlayerEnum.ROBOT && lobby.players[i].playerEnum != PlayerEnum.OFFLINE) { lobby.players[i].curServerDeal.next_step = ServerProcess.CALL_SCORE_PROCESS; lobby.players[i].curServerDeal.initProcessUpdate(); } } } break; //进入叫分环节(叫分阶段结束) case GameProcessEnum.CALL_SCORE: { if (intergation >= 3 || curCallScore % 4 == firstCallScore || reCallScoreNum == MAX_RE_CALLSCORE_NUM - 1) { //停止计时 timeCount.Stop(); //已经连续三局没人叫地主了,强制要求一个人当地主 if (reCallScoreNum == MAX_RE_CALLSCORE_NUM - 1 && intergation == 0) { reCallScoreNum = 0; //随机指定一个地主,叫分为1 intergation = 1; whoIsLand = random.Next(4); CallScoreProcess.setLandlord(whoIsLand, ref lobby); } //如果当前有人叫分 if (intergation > 0) { next_step = GameProcessEnum.OUT_CARD; //四名玩家同时进入出牌阶段(离线的玩家也要对其状态进行更新) for (int i = 0; i < 4; i++) { if (lobby.players[i].playerEnum != PlayerEnum.ROBOT && lobby.players[i].playerEnum != PlayerEnum.OFFLINE) { lobby.players[i].curServerDeal.next_step = ServerProcess.OUT_CARD_PROCESS; lobby.players[i].curServerDeal.initProcessUpdate(); } } } //如果当前没人叫分,则重新开始(三局之内) else if (reCallScoreNum < MAX_RE_CALLSCORE_NUM - 1) { //当前叫分轮数加一 reCallScoreNum++; next_step = GameProcessEnum.GAME_START; } } } break; //进入出牌阶段(出牌阶段结束) case GameProcessEnum.OUT_CARD: { //停止计时 timeCount.Stop(); //进行积分结算 peopleOperator.settleScore(peoples, intergation); //如果玩家不为机器人,将结算完的积分写入数据库 for (int i = 0; i < 4; i++) { if (lobby.players[i] != null && lobby.players[i].playerEnum != PlayerEnum.ROBOT) { string username = lobby.players[i].username; int score = peoples[i].integration; SqlDbHelper.ExecuteNonQuery ("update user_table set score = " + score + " where username = '******'"); } } //房间对剩余玩家进行处理,如果还剩玩家,将其放入大厅中,如果不剩,做销毁处理 if (lobby.dealTurnGame() == false) { destroyGameProcessDeal(); return; } //积分结算完等待下一局游戏开始 next_step = GameProcessEnum.GAME_START; } break; } //改变状态前的初始化 initProcessUpdate(); }
//游戏进程执行 private void executeProcess() { switch (step) { //游戏开始 case GameProcessEnum.GAME_START: { //初始化peoples和cardPile for (int i = 0; i < 4; i++) { peoples[i] = new People(); } cardPile = new List <Card>(); //洗牌,将卡发给四个人,留8张底牌 peopleOperator.shuffle(peoples, cardPile); //给每个人发卡组信息和底牌信息 string msg = "["; for (int i = 0; i < 4; i++) { msg += JsonHelper.sendCards("deck" + i, peoples[i].deck) + ","; } msg += JsonHelper.sendCards("cardPile", cardPile) + "]"; lobby.sendMesToAllPlayers(msg); //随机叫分的第一人 firstCallScore = random.Next(4); curCallScore = firstCallScore; //将消息发给四个人 lobby.sendMesToAllPlayers(JsonHelper.jsonObjectInt("firstCallScore", firstCallScore)); } break; //进入叫分环节(叫分阶段结束) case GameProcessEnum.CALL_SCORE: { startCallScore = true; int nowPeople = curCallScore; //记录当前的玩家 curCallScore = (curCallScore + 1) % 4; //轮到下一位玩家 //计算当前人叫分的时间(断线重连使用) timeCount.Restart(); //如果当前玩家处于断线状态或它是机器人,则自动认为不叫(等待一段时间) if (lobby.players[nowPeople] == null || lobby.players[nowPeople].playerEnum != PlayerEnum.PLAYING) { System.Timers.Timer t = new System.Timers.Timer(Constants.WAIT_AUTO_CALLSCORE_OUTCARD); t.AutoReset = false; t.Enabled = true; t.Elapsed += new ElapsedEventHandler(delegate(object sender, ElapsedEventArgs e) { //在其他地方已经把process给desroy了 if (lobby != null) { if (lobby.players[nowPeople] == null || lobby.players[nowPeople].playerEnum != PlayerEnum.PLAYING) { //如果是电脑可以不只是叫0分 int callScore = lobby.players[nowPeople] != null && lobby.players[nowPeople].playerEnum == PlayerEnum.ROBOT ? random.Next(4 - intergation) + intergation + 1 : 0; callScore = callScore > 3 ? 0 : callScore; CallScoreProcess.callScore(callScore, ref lobby.players[nowPeople]); } else { autoCallScoreThread[nowPeople] = new Thread(waitPeopleCallScore); timeCount.Stop(); ThreadMsg threadMsg = new ThreadMsg(nowPeople, Constants.WAIT_PEOPLE_CALL_SCORE - (int)timeCount.ElapsedMilliseconds / 1000); timeCount.Start(); autoCallScoreThread[nowPeople].Start(threadMsg); } } }); } //否则开启一个线程,如果玩家没能在指定时间内叫分,则自动叫分 else { autoCallScoreThread[nowPeople] = new Thread(waitPeopleCallScore); ThreadMsg threadMsg = new ThreadMsg(nowPeople, Constants.WAIT_PEOPLE_CALL_SCORE); autoCallScoreThread[nowPeople].Start(threadMsg); } } break; //进入出牌阶段(出牌阶段结束) case GameProcessEnum.OUT_CARD: { startOutCard = true; int nowPeople = curOutCard; //记录当前的玩家 curOutCard = (curOutCard + 1) % 4; //轮到下一位玩家 //计算当前人出牌的时间(断线重连使用) timeCount.Restart(); //如果当前玩家处于断线状态,则自动出牌 if (lobby.players[nowPeople] == null || lobby.players[nowPeople].playerEnum != PlayerEnum.PLAYING) { System.Timers.Timer t = new System.Timers.Timer(Constants.WAIT_AUTO_CALLSCORE_OUTCARD); t.AutoReset = false; t.Enabled = true; t.Elapsed += new ElapsedEventHandler(delegate(object sender, ElapsedEventArgs e) { //在其他地方已经把process给desroy了 if (lobby != null) { if (lobby.players[nowPeople] == null || lobby.players[nowPeople].playerEnum != PlayerEnum.PLAYING) { AIoutCard(nowPeople); } else { autoOutCardThread[nowPeople] = new Thread(waitPeopleOutCard); timeCount.Stop(); ThreadMsg threadMsg = new ThreadMsg(nowPeople, Constants.WAIT_PEOPLE_OUT_CARD - (int)timeCount.ElapsedMilliseconds / 1000); timeCount.Start(); autoOutCardThread[nowPeople].Start(threadMsg); } } }); } //否则开启一个线程,如果玩家没能在指定时间内出牌,则自动为其出牌,并设置托管 else { autoOutCardThread[nowPeople] = new Thread(waitPeopleOutCard); ThreadMsg threadMsg = new ThreadMsg(nowPeople, Constants.WAIT_PEOPLE_OUT_CARD); autoOutCardThread[nowPeople].Start(threadMsg); } } break; } //如果是游戏开始状态,执行一次直接进入下一状态 if (step == GameProcessEnum.GAME_START) { processUpdate(); } }