⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bot.cpp

📁 上面上传的autotools一文(也就是《使用GNU autotools 改造一个软件项目》)配套的示例程序源代码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//// Copyright (c) 2005, Wei Mingzhi <whistler@openoffice.org>// Portions copyright (c) 1994, 1995 Koji Suzuki <suz@d2.bs1.fc.nec.co.jp>// All Rights Reserved.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License as// published by the Free Software Foundation; either version 2 of// the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA// 02110-1301, USA//// Many parts of this file is based on Netmaj by Koji Suzuki// so credit goes to him.#include "main.h"#define DRAW_LOCATION(l) \   ((l >= 13) ? 640 - (20 + TILE_WIDTH * (l + 1) + 8) : 640 - (20 + TILE_WIDTH * (l + 1)))// Uncomment this to enable debug messages//#define BOT_DEBUGCBot::CBot(){}CBot::~CBot(){}void CBot::NewRound(){   m_BotBrain.goal = -1;   m_BotBrain.aggression = (float)m_iScore / (m_iScore + m_pOpponent->m_iScore);   m_BotBrain.aggression -= 0.5;   m_BotBrain.aggression *= 2;   m_BotBrain.num_handresult = 0;   CBasePlayer::NewRound();#ifdef BOT_DEBUG   fprintf(stdout, "*** NEW ROUND STARTED ***\n");#endif}void CBot::DrawHand(bool shown){   int i, j, loc = 0;   if (m_pOpponent->m_fReach) {      shown = true; // alway show computer's hand if player reached   }#ifdef BOT_DEBUG   shown = true;#endif   for (i = 0; i < m_Hand.m_iNumTileSets; i++) {      if ((m_Hand.m_TileSets[i].type & HT_OPEN) &&         !(m_Hand.m_TileSets[i].type & HT_RON))      {         if (m_Hand.m_TileSets[i].type & HT_OPENKONG) {            for (j = 0; j < 3; j++) {               gpGeneral->EraseArea(DRAW_LOCATION(loc), 10,                  TILE_WIDTH, 80);               gpGeneral->DrawTile(m_Hand.m_TileSets[i].first,                  DRAW_LOCATION(loc), 25, COMPUTER_SHOWN);               loc++;            }            // Draw another tile as it's a kong            gpGeneral->DrawTile(m_Hand.m_TileSets[i].first,               DRAW_LOCATION(loc - 2), 8, COMPUTER_SHOWN);         } else if (m_Hand.m_TileSets[i].type & HT_CLOSEDKONG) {            for (j = 0; j < 3; j++) {               gpGeneral->EraseArea(DRAW_LOCATION(loc), 10,                  TILE_WIDTH, 80);               gpGeneral->DrawTile(m_Hand.m_TileSets[i].first,                  DRAW_LOCATION(loc), 25, WALL_CONCEALED);               loc++;            }            // Draw another tile as it's a kong            gpGeneral->DrawTile(m_Hand.m_TileSets[i].first,               DRAW_LOCATION(loc - 2), 8, COMPUTER_SHOWN);         } else if (m_Hand.m_TileSets[i].type & HT_OPENPUNG) {            for (j = 0; j < 3; j++) {               gpGeneral->EraseArea(DRAW_LOCATION(loc), 10,                  TILE_WIDTH, 80);               gpGeneral->DrawTile(m_Hand.m_TileSets[i].first,                  DRAW_LOCATION(loc), 25, COMPUTER_SHOWN);               loc++;            }         } else if (m_Hand.m_TileSets[i].type & HT_OPENCHOW) {            CTile t = m_Hand.m_TileSets[i].first;            for (j = 0; j < 3; j++) {               gpGeneral->EraseArea(DRAW_LOCATION(loc), 10,                  TILE_WIDTH, 80);               gpGeneral->DrawTile(t, DRAW_LOCATION(loc),                  25, COMPUTER_SHOWN);               loc++;               t = t() + 1;            }         } else {            assert(false); // this should NOT happen         }      }   }   for (i = 0; i < m_Hand.m_iNumTiles; i++) {      if ((m_Hand.m_Tiles[i].flags & HT_OPEN) &&         !(m_Hand.m_Tiles[i].flags & HT_RON))      {         continue;      }      gpGeneral->EraseArea(DRAW_LOCATION(loc), 10,         TILE_WIDTH, 80);      gpGeneral->DrawTile(m_Hand.m_Tiles[i].tile,         DRAW_LOCATION(loc), shown ? 18 : 10,         shown ? COMPUTER_SHOWN : COMPUTER_CONCEALED);      loc++;   }   gpGeneral->EraseArea(0, 0, DRAW_LOCATION(loc - 1),      18 + TILE_HEIGHT_CONCEALED);   gpGeneral->UpdateScreen(0, 0, 640, 18 + TILE_HEIGHT_CONCEALED);}void CBot::DrawDiscarded(){   int i, x, y;   for (i = 0; i < 10 && i < m_iNumDiscarded - 10; i++) {      gpGeneral->DrawTile(m_Discarded[i + 10].tile, DRAW_LOCATION(i),         94, WALL_SHOWN);      if (m_Discarded[i + 10].flags & DT_REACH) {         bool locked = false;         if (SDL_MUSTLOCK(gpScreen)) {            SDL_LockSurface(gpScreen);            locked = true;         }         for (x = DRAW_LOCATION(i); x < DRAW_LOCATION(i) + TILE_WIDTH; x++) {            for (y = 94; y < 94 + TILE_HEIGHT_SHOWN; y++) {               unsigned char r, g, b;               UTIL_GetPixel(gpScreen, x, y, &r, &g, &b);               if (g >= 255 - 35) {                  g = 255;               } else {                  g += 35;               }               UTIL_PutPixel(gpScreen, x, y, r, g, b);            }         }         if (locked) {            SDL_UnlockSurface(gpScreen);         }      }   }   gpGeneral->EraseArea(DRAW_LOCATION(9), 94, TILE_WIDTH * (10 - i),      TILE_HEIGHT_SHOWN - 22);   for (i = 0; i < 10 && i < m_iNumDiscarded; i++) {      gpGeneral->DrawTile(m_Discarded[i].tile, DRAW_LOCATION(i),         132, WALL_SHOWN);      if (m_Discarded[i].flags & DT_REACH) {         bool locked = false;         if (SDL_MUSTLOCK(gpScreen)) {            SDL_LockSurface(gpScreen);            locked = true;         }         for (x = DRAW_LOCATION(i); x < DRAW_LOCATION(i) + TILE_WIDTH; x++) {            for (y = 132; y < 132 + TILE_HEIGHT_SHOWN; y++) {               unsigned char r, g, b;               UTIL_GetPixel(gpScreen, x, y, &r, &g, &b);               if (g >= 255 - 35) {                  g = 255;               } else {                  g += 35;               }               UTIL_PutPixel(gpScreen, x, y, r, g, b);            }         }         if (locked) {            SDL_UnlockSurface(gpScreen);         }      }   }   gpGeneral->EraseArea(DRAW_LOCATION(9), 132, TILE_WIDTH * (10 - i),      TILE_HEIGHT_SHOWN);   if (m_fReach) {      gpGeneral->DrawDotBar(DRAW_LOCATION(9) - 20, 99);   } else {      gpGeneral->EraseArea(DRAW_LOCATION(9) - 20, 99, 20, 85);   }   gpGeneral->UpdateScreen(DRAW_LOCATION(9) - 20, 94, 660 - DRAW_LOCATION(9),      TILE_HEIGHT_SHOWN * 2 - 22);}playeraction CBot::Action(enum actionstate state){   playeraction ret = PA_NONE;   int first = SDL_GetTicks();   if (ActionIsValid(state, PA_MAHJONG)) {      // Do we still need to think more as we've already won?      if (state == AS_DRAW) {         m_Hand.AddTile(m_pOpponent->LastDiscardedTile());      }      UTIL_Delay(800); // delay a while      return PA_MAHJONG; // we've already won the round   } else if ((m_iState & PS_KONGED) && state == AS_DRAW) {      m_BotBrain.action = PA_DRAW;   } else {      BotThink(state);   }   int time;   switch (state) {      case AS_DRAW:         ret = ActionDraw();         time = first + 300 - SDL_GetTicks();         if (time > 0) {            UTIL_Delay(time);         }         break;      case AS_DISCARD:         ret = ActionDiscard();         time = first + 350 - SDL_GetTicks();         if (time > 0) {            UTIL_Delay(time);         }         if (m_iLastDiscardIndex != -1) {            gpGeneral->EraseArea(DRAW_LOCATION(IndexToLoc(m_iLastDiscardIndex)),               10, TILE_WIDTH, 80);            gpGeneral->UpdateScreen(DRAW_LOCATION(IndexToLoc(m_iLastDiscardIndex)),               10, TILE_WIDTH, 80);            UTIL_Delay(100);         }         break;      default:         assert(false); // can this ever happen?         break;   }   return ret;}playeraction CBot::ActionDraw(){   if (IsRoundDraw()) {      return PA_NONE; // round has ended   }   int i;   switch (m_BotBrain.action) {      case PA_DRAW:         for (i = 0; i < m_Hand.m_iNumTiles; i++) {            m_Hand.m_Tiles[i].flags &= ~HT_JUSTGOT;         }         m_Hand.AddRandomTile(HT_JUSTGOT);         m_iState &= (PS_CALLREACH | PS_KONGED);         break;      case PA_CHOW:         if (!m_Hand.Chow(m_pOpponent->LastDiscardedTile(), m_BotBrain.chowlocation)) {            TerminateOnError("CBot::ActionDraw(): cannot chow");         }         m_pOpponent->m_iNumDiscarded--;         m_iState |= PS_ASKED;         break;      case PA_PUNG:         if (!m_Hand.Pung(m_pOpponent->LastDiscardedTile())) {            TerminateOnError("CBot::ActionDraw(): cannot pung");         }         m_pOpponent->m_iNumDiscarded--;         m_iState |= PS_ASKED;         break;      case PA_KONG:         if (!m_Hand.Kong(m_pOpponent->LastDiscardedTile())) {            TerminateOnError("CBot::ActionDraw(): cannot kong");         }         m_pOpponent->m_iNumDiscarded--;         m_iState |= (PS_ASKED | PS_KONGED);         break;      default:         TerminateOnError("CBot::ActionDraw(): unknown action");         break;   }   return m_BotBrain.action;}playeraction CBot::ActionDiscard(){   int index;   m_iLastDiscardIndex = -1;   switch (m_BotBrain.action) {      case PA_REACH:         gpGeneral->PlayBGMusic(-1);         gpGeneral->PlaySound(SND_REACH);         gpGeneral->DrawDotBar(DRAW_LOCATION(9) - 20, 99, true);         gpGeneral->UpdateScreen(DRAW_LOCATION(9) - 20, 99, 20, 85);         UTIL_Delay(800);         m_iState = PS_CALLREACH;         m_fReach = true;      case PA_DISCARD:         index = m_BotBrain.act_index;         if (index < 0 || index >= m_Hand.m_iNumTiles) {            TerminateOnError("CBot::ActionDiscard(): index out of range");         }         m_Discarded[m_iNumDiscarded].tile = m_Hand.m_Tiles[index].tile;         m_Discarded[m_iNumDiscarded].flags = 0;         m_iNumDiscarded++;         if (m_BotBrain.action == PA_REACH) {            m_Discarded[m_iNumDiscarded - 1].flags |= DT_REACH;            if (m_pOpponent->m_iNumDiscarded > 0) {               m_pOpponent->m_Discarded[m_pOpponent->m_iNumDiscarded - 1].flags |= DT_OPPONENTREACH;            }         } else {            m_iState = 0;         }         m_Hand.RemoveTile(index);         m_iLastDiscardIndex = index;         for (index = 0; index < m_Hand.m_iNumTiles; index++) {            m_Hand.m_Tiles[index].flags &= ~HT_JUSTGOT;         }         m_Hand.Sort();         break;      case PA_KONG:         if (!m_Hand.Kong(m_Hand.m_Tiles[m_BotBrain.act_index].tile, false)) {            TerminateOnError("CBot::ActionDiscard(): cannot kong");         }         m_iState |= PS_KONGED;         break;      default:         TerminateOnError("CBot::ActionDiscard(): unknown bot action");         break;   }   return m_BotBrain.action;}void CBot::BotThink(enum actionstate state){#ifdef BOT_DEBUG   fprintf(stdout, "=== CBot::BotThink() begin ===\n");#endif   int i;   if (m_fReach) {      // we've reached, no need to think too much      if (state == AS_DRAW) {         // we can do nothing other than drawing a tile now         m_BotBrain.action = PA_DRAW;      } else if (state == AS_DISCARD) {         // check if we can declare a kong, and after declaring         // we still have a ready hand...         for (i = m_Hand.m_iNumTiles - 1; i >= 0; i--) {            if ((m_Hand.m_Tiles[i].flags & HT_JUSTGOT) == 0) {               continue;            }            m_BotBrain.act_index = i;            CHand tmp = m_Hand;            if (tmp.Kong(m_Hand.m_Tiles[i].tile, false)) {               if (tmp.IsReady()) {                  m_BotBrain.action = PA_KONG;                  return;               }            }            break;         }         m_BotBrain.action = PA_DISCARD;      } else {         TerminateOnError("CBot::BotThink(): unknown action state");      }      return;   }   UpdateStatus();   switch (state) {      case AS_DRAW:         m_BotBrain.action = PA_DRAW;         if (WantToChow()) {#ifdef BOT_DEBUG            fprintf(stdout, "Bot want to chow\n");#endif         }         if (WantToPung()) {#ifdef BOT_DEBUG            fprintf(stdout, "Bot want to pung\n");#endif         }         if (WantToOpenKong()) {#ifdef BOT_DEBUG            fprintf(stdout, "Bot want to open kong\n");#endif         }         break;      case AS_DISCARD:         m_BotBrain.action = PA_DISCARD;         if (m_BotBrain.action == PA_DISCARD ||            m_BotBrain.action == PA_REACH) {            AnalyzeDiscard();         }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -