📄 gamecontrol.cc
字号:
/* * TITLE: gamecontrol.cc * * PURPOSE: Wraps the game control functionality for keeping track of time, and other * game info. * * WRITTEN BY: Brett Browning *//* LICENSE: ========================================================================= RoboCup F180 Referee Box Source Code Release ------------------------------------------------------------------------- Copyright (C) 2003 RoboCup Federation ------------------------------------------------------------------------- This software is distributed under the GNU General Public License, version 2. If you do not have a copy of this licence, visit www.gnu.org, or write: Free Software Foundation, 59 Temple Place, Suite 330 Boston, MA 02111-1307 USA. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ------------------------------------------------------------------------- */#include <cstdio>#include <time.h>#include <sys/time.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include "commands.h"#include "gamecontrol.h"//#include "serial.h"#define MAX_LINE 256#define CHOOSETEAM(t, blue, yel) (((t) == Blue) ? (blue) : (yel))// initializes sets up everythingbool GameControl::init(char *confname, char *logfname, bool restart) { enabled = true;// #ifdef WIN32// serdev = "COM1:";// #else// serdev = "/dev/ttyS0";// #endif if (!readFile(confname)) { fprintf(stderr, "ERROR: Cannot read config file %s\n", confname); return (false); } // a little user output print();// /* open the serial port */// fprintf(stderr, "Opening Serial Connection on device %s ...\n", serdev);// if (!serial.Open(serdev, COMM_BAUD_RATE)) {// fprintf(stderr, "ERROR: Cannot open serial connection..\n");// return (false);// } // STF std::cout << "Creating TcpcServer ... " << std::endl; m_pTcpcServer = new TcpcServer(m_iServerPort, m_iNumberOfRequiredConnections); std::cout << "Starting TcpcServer ... " << std::endl; m_pTcpcServer->StartUp(); // intialize the timer gameinfo.resetTimer(); tlast = getTime(); if (!gameinfo.openLog(logfname)) { fprintf(stderr, "ERROR: Cannot open log file %s..\n", logfname); return (false); } // restart from saved state if (restart) { gameinfo.load(savename); } return (true);} void GameControl::close() { gameinfo.closeLog(); // serial.Close(); // STF m_pTcpcServer->ShutDown();}void GameControl::print(FILE *f) { fprintf(f, "Game Settings\n"); fprintf(f, "\ttimelimits : First Half %i:%02i\n", DISP_MIN(gameinfo.data.timelimits[FIRST_HALF]), DISP_SEC(gameinfo.data.timelimits[FIRST_HALF])); fprintf(f, "\t\tHalf time %i:%02i\n", DISP_MIN(gameinfo.data.timelimits[HALF_TIME]), DISP_SEC(gameinfo.data.timelimits[HALF_TIME])); fprintf(f, "\t\tSecond half %i:%02i\n", DISP_MIN(gameinfo.data.timelimits[SECOND_HALF]), DISP_SEC(gameinfo.data.timelimits[SECOND_HALF])); fprintf(f, "\t\tOvertime %i:%02i\n", DISP_MIN(gameinfo.data.timelimits[OVER_TIME1]), DISP_SEC(gameinfo.data.timelimits[OVER_TIME1])); fprintf(f, "\t\tOvertime %i:%02i\n", DISP_MIN(gameinfo.data.timelimits[OVER_TIME2]), DISP_SEC(gameinfo.data.timelimits[OVER_TIME2]));}/////////////////////////////// send commands// log commands, send them over serial and change game statevoid GameControl::sendCommand(int cmd, const char *msg) { gameinfo.writeLog("Sending %c: %s", cmd, msg); //serial.WriteByte(cmd); // STF m_pTcpcServer->SendCommand(cmd);}void GameControl::stepTime() { double tnew = getTime(); double dt = tnew - tlast; tlast = tnew; // save restore file gameinfo.save(savename); // update game time gameinfo.data.gametime += dt; if ((gameinfo.data.stage == HALF_TIME) || !gameinfo.isHalted()) { gameinfo.data.time_taken += dt; } if (gameinfo.isTimeComplete()) { switch (gameinfo.data.stage) { case PREGAME: case PRESECONDHALF: case PREOVERTIME1: case PREOVERTIME2: break; case FIRST_HALF: beginHalfTime(); break; case HALF_TIME: beginSecondHalf(); break; case SECOND_HALF: if (gameinfo.isGameTied()) beginOvertime1(); break; case OVER_TIME1: beginOvertime2(); break; case OVER_TIME2: if (gameinfo.isGameTied()) beginPenaltyShootout(); break; case PENALTY_SHOOTOUT: break; } }}////////////////////////////////////////// configuration// read a config file to fill in parametersbool GameControl::readFile(char *fname) { FILE *f; char line[MAX_LINE], dname[MAX_LINE], data[MAX_LINE]; double d; int i; // open the file if ((f = fopen(fname, "rt")) == NULL) { fprintf(stderr, "ERROR: Readfile: cannot open file %s\n", fname); return (false); } while (fgets(line, MAX_LINE, f) != NULL) { if ((line[0] != '#') && (strchr(line, '=') != NULL)) { if (sscanf(line, " %[a-z_A-Z0-9] = %s", dname, data) == 2) { if (strcmp(dname, "SAVENAME") == 0) { savename = new char[MAX_LINE]; strncpy(savename, data, MAX_LINE - 1); } else if (strcmp(dname, "SERIALDEVICE") == 0) {// serdev = new char[MAX_LINE];// strncpy(serdev, data, MAX_LINE - 1); } else if (strcmp(dname, "FIRST_HALF") == 0) { sscanf(data, " %lf", &d); gameinfo.data.timelimits[FIRST_HALF] = MIN2SEC(d); } else if (strcmp(dname, "HALF_TIME") == 0) { sscanf(data, " %lf", &d); gameinfo.data.timelimits[HALF_TIME] = MIN2SEC(d); } else if (strcmp(dname, "SECOND_HALF") == 0) { sscanf(data, " %lf", &d); gameinfo.data.timelimits[SECOND_HALF] = MIN2SEC(d); } else if (strcmp(dname, "OVER_TIME") == 0) { sscanf(data, " %lf", &d); gameinfo.data.timelimits[OVER_TIME1] = MIN2SEC(d); gameinfo.data.timelimits[OVER_TIME2] = MIN2SEC(d); } else if (strcmp(dname, "SERVER_PORT") == 0) { sscanf(data, " %d", &i); m_iServerPort = i; } else if (strcmp(dname, "NUMBER_OF_REQUIRED_CONNECTIONS") == 0) { sscanf(data, " %d", &i); m_iNumberOfRequiredConnections = i; } else { fprintf(stderr, "Unrecognized parameter %s, will be ignored\n", dname); } } } } // all done fclose(f); return (true);}/////////////////////////////// game stage commandsbool GameControl::beginFirstHalf(){ if (enabled) { if (gameinfo.data.stage != PREGAME) return (false); // send the first half signal but we do not oficially begin // until start signal is sent setHalt(); } sendCommand(COMM_FIRST_HALF, "Begin first half"); return (true);}bool GameControl::beginHalfTime() { if (enabled) { if (gameinfo.data.stage != FIRST_HALF) return (false); gameinfo.data.stage = HALF_TIME; setHalt(); gameinfo.resetTimer(); } sendCommand(COMM_HALF_TIME, "Begin half time"); return (true);}bool GameControl::beginSecondHalf(){ if (enabled) { if (gameinfo.data.stage != HALF_TIME) return (false); // again we send signal, but do not officially begin until // start is sent setHalt(); gameinfo.data.stage = PRESECONDHALF; } sendCommand(COMM_SECOND_HALF, "Begin second half"); return (true);}bool GameControl::beginOvertime1(){ if (enabled) { if (gameinfo.data.stage != SECOND_HALF) return (false); gameinfo.data.stage = PREOVERTIME1; setHalt(); gameinfo.resetTimer(); } sendCommand(COMM_OVER_TIME1, "Begin overtime"); return (true);}bool GameControl::beginOvertime2(){ if (enabled) { if (gameinfo.data.stage != OVER_TIME1) return (false); gameinfo.data.stage = PREOVERTIME2; setHalt(); gameinfo.resetTimer(); } sendCommand(COMM_OVER_TIME2, "Begin overtime second half"); return (true);}bool GameControl::beginPenaltyShootout(){ if (enabled) { if ((gameinfo.data.stage != OVER_TIME2) && (gameinfo.data.stage != SECOND_HALF)) { return (false); } gameinfo.data.stage = PENALTY_SHOOTOUT; setHalt(); gameinfo.resetTimer(); } sendCommand(COMM_FIRST_HALF, "Begin Penalty shootout"); return (true);}/////////////////////////////////// game control commandsbool GameControl::setHalt(){ if (enabled) { gameinfo.data.state = HALTED; } sendCommand(COMM_HALT, "Halting robots"); return (true);}bool GameControl::setReady(){ if (!enabled) { sendCommand(COMM_READY, "STarting robots"); } else { if (!gameinfo.isTimeout() && gameinfo.isPrestart()) { sendCommand(COMM_READY, "STarting robots"); gameinfo.setRunning(); // progress into teh first half upon the start signal switch (gameinfo.data.stage) { case PREGAME: gameinfo.data.stage = FIRST_HALF; gameinfo.resetTimer(); break; case PRESECONDHALF: gameinfo.data.stage = SECOND_HALF; gameinfo.resetTimer(); break; case PREOVERTIME1: gameinfo.data.stage = OVER_TIME1; gameinfo.resetTimer(); break; case PREOVERTIME2: gameinfo.data.stage = OVER_TIME2; gameinfo.resetTimer(); break; } } } return (true);}bool GameControl::setStart(){ if (!enabled) { sendCommand(COMM_START, "STarting robots"); } else { if (!gameinfo.isTimeout() && gameinfo.isStopped()) { sendCommand(COMM_START, "STarting robots"); gameinfo.setRunning(); // progress into teh first half upon the start signal switch (gameinfo.data.stage) { case PREGAME: gameinfo.data.stage = FIRST_HALF; gameinfo.resetTimer(); break; case PRESECONDHALF: gameinfo.data.stage = SECOND_HALF; gameinfo.resetTimer(); break; case PREOVERTIME1: gameinfo.data.stage = OVER_TIME1; gameinfo.resetTimer(); break; case PREOVERTIME2: gameinfo.data.stage = OVER_TIME2; gameinfo.resetTimer(); break; } } } return true;}bool GameControl::setStop(){ sendCommand(COMM_STOP, "Stopping robots"); if (enabled) { // progress out of half time if we hit stop if (gameinfo.data.stage == HALF_TIME) { beginSecondHalf(); gameinfo.setStopped(); } else { gameinfo.setStopped(); } } return (true);}// maybe deprecatebool GameControl::setCancel(){ sendCommand(COMM_CANCEL, "Sending cancel"); return (true);}// status commandsbool GameControl::goalScored(Team team){ if (enabled) { if (!gameinfo.isStopped() && !gameinfo.isHalted() || (gameinfo.data.stage == PREGAME)) return (false); if (gameinfo.data.stage == PENALTY_SHOOTOUT) { gameinfo.data.penaltygoals[(int) team]++; } else { gameinfo.data.goals[(int) team]++; } } char msg[256]; sendCommand(CHOOSETEAM(team, COMM_GOAL_BLUE, COMM_GOAL_YELLOW), concatTeam(msg, "Goal scored", team)); return (true);}bool GameControl::removeGoal(Team team){ if (enabled) { if (!gameinfo.isStopped() && !gameinfo.isHalted() || (gameinfo.data.stage == PREGAME)) return (false); if (gameinfo.data.stage == PENALTY_SHOOTOUT) { if (gameinfo.data.penaltygoals[(int) team] > 0) gameinfo.data.penaltygoals[(int) team]--; } else if (gameinfo.data.goals[team] > 0) { gameinfo.data.goals[(int) team]--; } } char msg[256]; sendCommand(CHOOSETEAM(team, COMM_SUBGOAL_BLUE, COMM_SUBGOAL_YELLOW), concatTeam(msg, "Goal removed", team)); return (true);}// game restart commandsbool GameControl::setKickoff(Team team){ if (enabled) { if (!gameinfo.isStopped() || !gameinfo.canRestart()) return (false); gameinfo.setPrestart(); } char msg[256]; sendCommand(CHOOSETEAM(team, COMM_KICKOFF_BLUE, COMM_KICKOFF_YELLOW), concatTeam(msg, "Kickoff", team)); return (true);}bool GameControl::setPenalty(Team team){ if (enabled) { if (!gameinfo.isStopped() || !gameinfo.canRestart()) return (false); gameinfo.setPrestart(); } char msg[256]; sendCommand(CHOOSETEAM(team, COMM_PENALTY_BLUE, COMM_PENALTY_YELLOW), concatTeam(msg, "Penalty kick", team)); return (true);}bool GameControl::setThrowin(){ if (enabled) { if (!gameinfo.isStopped() || !gameinfo.canRestart()) return (false); gameinfo.setPrestart(); } char msg[256]; sendCommand(COMM_THROWIN, "Throwin"); return (true);}bool GameControl::setCorner(){ if (enabled) { if (!gameinfo.isStopped() || !gameinfo.canRestart()) return (false); gameinfo.setPrestart(); } char msg[256]; sendCommand(COMM_CORNER, "Corner"); return (true);}char *GameControl::concatTeam(char *msg, const char *msgpart, Team team){ strcpy(msg, msgpart); if (team == Blue) strcat(msg, " Blue"); else strcat(msg, " Yellow"); return (msg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -