/* PegBoard: An Implementation of Triangle Peg Solitaire Copyright (C) 2004 by Jeffrey K. Brown (Jkb) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. http://www.gnu.org/copyleft/gpl.html Contact: Jeffrey K. Brown (Jkb) jkb@darkfantastic.net http://jkb.tdf.ca http://jkb.tdf.ca/doc/pegboard/ Dark Ages Talker - telnet://darkfantastic.net:2121 */ /**********************************************************************/ /* Author's Notes: These routines are for NUTS 2.3 Talkers. You can easily modify them to fit NUTS 3.3 or NUTS derivatives. It's just a matter of properly identifying the structure in use and changing the socket printing function's name, not reengineering the game. Changing the name of the structures does not change the program, so please don't try to rebrand PegBoard and pass it off as your own. Treat the "You should have received a copy of the GNU General Public License..." line as "See that link? Click it. There's your copy." Finally, if you would like help implementing this on your talker, or have questions, or found a bug or something, feel free to contact me at the address above. Enjoy the program, it was fun to write. - Jkb */ /**********************************************************************/ /* Add the following variables to the User Structure. This will allow all users online to play their own PegBoard game. I will also suggest you use bool here and later in the code, change the 1's and 0's to "true" and "false". A bool is 1 bit, while a short is 2 bytes, while and int is 4 bytes on many platforms. short int pega; short int pegb; short int pegc; short int pegd; short int pege; short int pegf; short int pegg; short int pegh; short int pegi; short int pegj; short int pegk; short int pegl; short int pegm; short int pegn; short int pego; short int started; char history[500]; short int movecount; char moves[500]; */ /**********************************************************************/ /* resetPegs(): This assumes you want a new game and resets the game variables. Then, if the display variable is set, it displays the board. Talker: Map a command .resetpeg or something to resetpegs(user, 1) to clear the game and display the new options. Substitute your talker's user identifier for 'user'. */ int resetPegs(int user, int display) { ustr[user].started=0; strcpy(ustr[user].history,""); ustr[user].movecount=0; ustr[user].pega=1; ustr[user].pegb=1; ustr[user].pegc=1; ustr[user].pegd=1; ustr[user].pege=1; ustr[user].pegf=1; ustr[user].pegg=1; ustr[user].pegh=1; ustr[user].pegi=1; ustr[user].pegj=1; ustr[user].pegk=1; ustr[user].pegl=1; ustr[user].pegm=1; ustr[user].pegn=1; ustr[user].pego=1; strcpy(ustr[user].moves,""); startPeg(user); if (display==1) displayPegBoard(user); return 0; } /**********************************************************************/ /* startPeg(): This randomly selects a starting peg and removes it. You can't play PegBoard unless you start somewhere. This starts the game. Talker: Don't map this function to a command. */ void startPeg(int user) { int peg=0; ustr[user].started=1; ustr[user].movecount++; peg = rand() % 15; if (peg==0) ustr[user].pega=0; if (peg==1) ustr[user].pegb=0; if (peg==2) ustr[user].pegc=0; if (peg==3) ustr[user].pegd=0; if (peg==4) ustr[user].pege=0; if (peg==5) ustr[user].pegf=0; if (peg==6) ustr[user].pegg=0; if (peg==7) ustr[user].pegh=0; if (peg==8) ustr[user].pegi=0; if (peg==9) ustr[user].pegj=0; if (peg==10) ustr[user].pegk=0; if (peg==11) ustr[user].pegl=0; if (peg==12) ustr[user].pegm=0; if (peg==13) ustr[user].pegn=0; if (peg==14) ustr[user].pego=0; } /**********************************************************************/ /* displayPegBoard(): This will print the board, the number of moves, the moves made already and the available moves. If no more moves are available, it will print the score. Talker: If you want, you can map a .displaypegboard command to this function. Personally, I think it's redundant, as you get the board printed after you move, but I suppose you could play PegBoard while chatting. */ int displayPegBoard(int user) { char la, lb, lc, ld, le, lf, lg, lh, li, lj, lk, ll, lm, ln, lo; if (ustr[user].pega==1) la = 'A'; else la = '.'; if (ustr[user].pegb==1) lb = 'B'; else lb = '.'; if (ustr[user].pegc==1) lc = 'C'; else lc = '.'; if (ustr[user].pegd==1) ld = 'D'; else ld = '.'; if (ustr[user].pege==1) le = 'E'; else le = '.'; if (ustr[user].pegf==1) lf = 'F'; else lf = '.'; if (ustr[user].pegg==1) lg = 'G'; else lg = '.'; if (ustr[user].pegh==1) lh = 'H'; else lh = '.'; if (ustr[user].pegi==1) li = 'I'; else li = '.'; if (ustr[user].pegj==1) lj = 'J'; else lj = '.'; if (ustr[user].pegk==1) lk = 'K'; else lk = '.'; if (ustr[user].pegl==1) ll = 'L'; else ll = '.'; if (ustr[user].pegm==1) lm = 'M'; else lm = '.'; if (ustr[user].pegn==1) ln = 'N'; else ln = '.'; if (ustr[user].pego==1) lo = 'O'; else lo = '.'; write_user(user,"\n\r"); sprintf(mess, "------------------------------------------------\n\r"); write_user(user,mess); sprintf(mess, "PegBoard, by Jkb (http://jkb.tdf.ca/)\n\r"); write_user(user,mess); sprintf(mess, " To Reset: .resetpeg\n\r"); write_user(user,mess); sprintf(mess, " To Play: .movepeg move\n\r"); write_user(user,mess); sprintf(mess, "Moves: %d\n\r", ustr[user].movecount); write_user(user,mess); sprintf(mess, "Game: %s\n\r", ustr[user].history); write_user(user,mess); sprintf(mess, " %c\n\r", la); write_user(user,mess); sprintf(mess, " %c %c\n\r", lb, lc); write_user(user,mess); sprintf(mess, " %c %c %c\n\r", ld, le, lf); write_user(user,mess); sprintf(mess, " %c %c %c %c\n\r", lg, lh, li, lj); write_user(user,mess); sprintf(mess, " %c %c %c %c %c\n\r", lk, ll, lm, ln, lo); write_user(user,mess); sprintf(mess, "\n Moves: %s\n\r", getMoves(user)); write_user(user,mess); if (strcmp(getMoves(user),"None")==0) { sprintf(mess, "Score: %d\n\r", getPegScore(user)); write_user(user,mess); } return 0; } /**********************************************************************/ /* togglePeg(): This will toggle pegs from true to false. One specifies a move by naming the three pegs in order. You can simply take 2 trues and a false and 'not' them to 2 falses and a true, which coincidentally is how a PegBoard move looks. Talker: Don't do anything. This is an internal function. */ int togglePeg(int user, char peg) { if (peg=='A') { ustr[user].pega = !ustr[user].pega; } if (peg=='B') { ustr[user].pegb = !ustr[user].pegb; } if (peg=='C') { ustr[user].pegc = !ustr[user].pegc; } if (peg=='D') { ustr[user].pegd = !ustr[user].pegd; } if (peg=='E') { ustr[user].pege = !ustr[user].pege; } if (peg=='F') { ustr[user].pegf = !ustr[user].pegf; } if (peg=='G') { ustr[user].pegg = !ustr[user].pegg; } if (peg=='H') { ustr[user].pegh = !ustr[user].pegh; } if (peg=='I') { ustr[user].pegi = !ustr[user].pegi; } if (peg=='J') { ustr[user].pegj = !ustr[user].pegj; } if (peg=='K') { ustr[user].pegk = !ustr[user].pegk; } if (peg=='L') { ustr[user].pegl = !ustr[user].pegl; } if (peg=='M') { ustr[user].pegm = !ustr[user].pegm; } if (peg=='N') { ustr[user].pegn = !ustr[user].pegn; } if (peg=='O') { ustr[user].pego = !ustr[user].pego; } return 0; } /**********************************************************************/ /* movePeg(): This function is used to input a move. A user will enter the move, which is then error-checked and then compared with the available moves. If it is properly formatted and available, the pegs in the move are then toggled. Talker: Map this function to a .movepeg command. */ int movePeg (int user, char* rawmove) { char move[10]; int i=0; if ((strlen(rawmove)>3) || (strlen(rawmove)<3) ) { write_user(user, "Illegally Formatted Move!\n\r"); return 1; } else { strcpy(move, rawmove); } for (i=0; i