This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
NeoStats-warserv/play.c

553 lines
15 KiB
C
Raw Permalink Normal View History

/* WarServ - War Card Game Service - NeoStats Addon Module
2008-03-10 07:39:20 +00:00
** Copyright (c) 2004-2008 Justin Hammond, Mark Hetherington, Jeff Lang
**
** 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
**
** WarServ CVS Identification
** $Id$
*/
#include "neostats.h" /* Required for bot support */
#include "warserv.h"
2005-10-18 20:45:51 +00:00
char warroom[MAXCHANLEN];
int currentwargamestatus;
int currentwarplayercount;
char wplayernick[10][MAXNICK];
int wplayercardstotal[10];
2005-10-18 21:11:37 +00:00
int warinprogress;
int currentplayer;
int wpln;
2005-10-18 20:57:13 +00:00
static int wplayercardsinhand[10][52];
static int wplayercardplayed[10];
static int wplayeratwar[10];
static int wplayerwarcardsplayed[10][3];
static int wstackcards[52];
static int wstackcardscurrent;
static char csuit[10];
static char csuitcolour[10];
static char csuitcard[10];
static void checkhandwinner(void);
static void checkwarwinner(void);
static void clearstack(void);
static void playershufflecards(void);
static void wardealcards(void);
static void askplaycard(void);
int startwar(void *userptr);
2005-10-18 20:45:51 +00:00
/*
* Stop Game
* resets everything to default as if no game running
*/
void stopwar(void)
{
int i;
if (currentwargamestatus == WS_GAME_STARTING) {
DelTimer ("startwar");
}
for (wpln = 0; wpln < 10; wpln++) {
strlcpy (wplayernick[wpln], " ", MAXNICK);
wplayercardstotal[wpln]= 0;
wplayercardplayed[wpln]= 0;
wplayeratwar[wpln]= 0;
for (i = 0; i < 52; i++) {
wplayercardsinhand[wpln][i]= 0;
}
for (i = 0; i < 3; i++) {
wplayerwarcardsplayed[wpln][i]= 0;
}
}
for (wpln = 0; wpln < 52; wpln++) {
wstackcards[wpln]= 0;
}
warinprogress= 0;
wstackcardscurrent= 0;
currentwarplayercount = 0;
currentwargamestatus = WS_GAME_STOPPED;
currentplayer= 0;
return;
}
/*
* Start Game Countdown
* Starts a timer to allow 30 seconds for people to join the game
*/
void startcountdowntimer(char *nic) {
currentwargamestatus = WS_GAME_STARTING;
irc_chanprivmsg (ws_bot, warroom, "\0037A new game of \0034WAR\0037 has been started by %s. Game will start in 30 seconds, type '\2\003!Join\2\0037' to play.", nic);
2005-08-09 13:05:00 +00:00
AddTimer (TIMER_TYPE_COUNTDOWN, startwar, "startwar", 30, NULL);
return;
}
/*
* Start Game
* Initializes variables and starts game
*/
2005-10-18 20:57:13 +00:00
int startwar(void *userptr)
{
/* DelTimer ("startwar"); */
if (currentwargamestatus == WS_GAME_STARTING) {
if (currentwarplayercount < 1) {
irc_chanprivmsg (ws_bot, warroom, "\0034No Players joined to current Game, Exiting");
currentwargamestatus = WS_GAME_STOPPING;
stopwar();
2005-02-24 21:18:11 +00:00
return NS_SUCCESS;
}
if (currentwarplayercount < 10) {
joinwar(ws_bot->name);
}
irc_chanprivmsg (ws_bot, warroom, "\0034WAR\00310 is now starting, current players are \0037%s %s %s %s %s %s %s %s %s %s", wplayernick[0], wplayernick[1], wplayernick[2], wplayernick[3], wplayernick[4], wplayernick[5], wplayernick[6], wplayernick[7], wplayernick[8], wplayernick[9]);
irc_chanprivmsg (ws_bot, warroom, "\0039Shuffling Deck and Dealing Cards");
currentplayer= 0;
currentwargamestatus = WS_GAME_PLAYING;
wardealcards();
wstackcardscurrent= 0;
askplaycard();
}
2005-02-24 21:18:11 +00:00
return NS_SUCCESS;
}
/*
* Join Game
* adds new player to game during countdown
*/
void joinwar(char *nic) {
if (currentwarplayercount < 10) {
for (wpln = 0; wpln < 10; wpln++) {
if (!ircstrcasecmp (wplayernick[wpln], nic)) {
return;
}
}
strlcpy (wplayernick[currentwarplayercount], nic, MAXNICK);
currentwarplayercount++;
irc_chanprivmsg (ws_bot, warroom, "\0038Welcome to \0034WAR \0037%s", nic);
} else {
irc_chanprivmsg (ws_bot, warroom, "\0034Sorry all places are filled \0037%s\0034, your welcome to try the next game though", nic);
}
}
/*
* Remove Player
* removes player from game and adds any cards they have to the stack
*/
void removewar(char *nic)
{
int i;
int tfrpacp;
int tfrpacpn;
int wplnht;
int cpfp;
tfrpacp= 0;
tfrpacpn= 0;
if (currentwarplayercount < 1) {
return;
}
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
if (!ircstrcasecmp (wplayernick[wpln], nic)) {
irc_chanprivmsg (ws_bot, warroom, "\0037%s \0038Removed from the current game of \0034War", nic);
if (wpln == currentplayer) {
tfrpacp= 1;
} else if (wpln < currentplayer) {
tfrpacp= 2;
tfrpacpn= wpln;
}
for (wplnht = 0; wplnht < wplayercardstotal[wpln]; wplnht++) {
wstackcards[wstackcardscurrent]= wplayercardsinhand[wpln][wplnht];
wstackcardscurrent++;
}
for (i = wpln; i < currentwarplayercount; i++) {
cpfp= (i + 1);
if (cpfp == currentwarplayercount) {
strlcpy (wplayernick[i], " ", MAXNICK);
for (wplnht = 0; wplnht < wplayercardstotal[i]; wplnht++) {
wplayercardsinhand[i][wplnht]= 0;
}
wplayercardstotal[i]= 0;
} else {
strlcpy (wplayernick[i], wplayernick[cpfp], MAXNICK);
for (wplnht = 0; wplnht < 52; wplnht++) {
wplayercardsinhand[i][wplnht]= wplayercardsinhand[cpfp][wplnht];
}
wplayercardstotal[i]= wplayercardstotal[cpfp];
}
}
currentwarplayercount--;
}
}
if (currentwarplayercount < 2) {
irc_chanprivmsg (ws_bot, warroom, "\0039Stopping Current Game , \0037%s\0039 wins.", wplayernick[0]);
stopwar();
} else if (tfrpacp == 1) {
if (currentplayer > (currentwarplayercount - 1)) {
currentplayer= 0;
}
if (currentwargamestatus == WS_GAME_STARTING) {
askplaycard();
}
} else if (tfrpacp == 2) {
if (currentplayer > tfrpacpn) {
currentplayer--;
}
}
}
/*
* Deal Cards
*/
2005-10-18 20:57:13 +00:00
static void wardealcards(void) {
int cd;
int cnd;
int cndn;
int ptdt = 0;
for (wpln = 0; wpln < 52; wpln++) {
wstackcards[wpln]= wpln;
}
for (cd = 52; cd > 0; cd--) {
cnd= rand() % cd;
cndn= wstackcards[cnd];
for (wpln = cnd; wpln < (cd - 1); wpln++) {
wstackcards[wpln]= wstackcards[(wpln + 1)];
}
wstackcards[(cd - 1)]= 0;
wplayercardsinhand[ptdt][wplayercardstotal[ptdt]]= cndn;
wplayercardstotal[ptdt]++;
ptdt++;
if (ptdt == currentwarplayercount) {
ptdt= 0;
}
}
}
/*
* Shuffle Players Cards
*/
void playershufflecards(void)
{
int tcs;
int tcsp;
int tcsps;
int i;
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
for (i = 0; i < wplayercardstotal[wpln]; i++) {
tcsps= 0;
tcsp= rand() % wplayercardstotal[wpln];
if (tcsp == i) {
tcsps= 1;
}
if (tcsps == 0) {
tcs= wplayercardsinhand[wpln][tcsp];
wplayercardsinhand[wpln][tcsp] = wplayercardsinhand[wpln][i];
wplayercardsinhand[wpln][i] = tcs;
}
}
}
}
/*
* asks each player for card to play
* or check war results if in war
* or removes player if no cards left
*/
2005-10-18 20:57:13 +00:00
static void askplaycard(void)
{
int trn;
int wspa[5];
int nwp = (currentwarplayercount + 1);
if (wplayercardstotal[currentplayer] == 0) {
removewar(wplayernick[currentplayer]);
}
if (wplayercardstotal[currentplayer] == 52) {
currentplayer++;
removewar(wplayernick[currentplayer]);
}
if (currentwarplayercount < 2) {
return;
}
if (warinprogress == 1) {
if (currentplayer < currentwarplayercount) {
for (wpln = currentplayer; wpln < currentwarplayercount; wpln++) {
if (wplayeratwar[wpln] == 1) {
nwp= wpln;
wpln= currentwarplayercount;
}
}
currentplayer = nwp;
}
if (nwp > currentwarplayercount) {
checkwarwinner();
} else {
if (!ircstrcasecmp (wplayernick[currentplayer], ws_bot->name)) {
trn= wplayercardstotal[currentplayer];
wspa[2]= ((rand() % trn) + 1);
trn--;
wspa[3]= ((rand() % trn) + 1);
if (wspa[3] == wspa[2]) {
wspa[3]++;
}
trn--;
wspa[4]= ((rand() % trn) + 1);
if ((wspa[4] == wspa[2]) || (wspa[4] == wspa[3])) {
wspa[4]++;
}
if ((wspa[4] == wspa[2]) || (wspa[4] == wspa[3])) {
wspa[4]++;
}
playwarcards(wspa[2], wspa[3], wspa[4]);
} else {
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 you hold\00311 %d\0039 cards, and are currently at \0034WAR\0039 which three would you like to play ?", wplayernick[currentplayer], wplayercardstotal[currentplayer]);
}
}
} else {
if (!ircstrcasecmp (wplayernick[currentplayer], ws_bot->name)) {
playcard(((rand() % wplayercardstotal[currentplayer]) + 1));
} else {
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 you currently hold\00311 %d\0039 cards, which would you like to play ?", wplayernick[currentplayer], wplayercardstotal[currentplayer]);
}
}
}
/*
* Player War Play Card
*/
void playwarcards(int cnp1, int cnp2, int cnp3)
{
int i;
int cnp[3];
cnp[0] = cnp1;
cnp[1] = cnp2;
cnp[2] = cnp3;
for (wpln = 0; wpln < 3; wpln++) {
if ((cnp[wpln] < 1) || (cnp[wpln] > wplayercardstotal[currentplayer])) {
return;
}
}
if (wplayercardsinhand[currentplayer][(cnp[2] - 1)] < 13) {
strlcpy (csuitcolour, "\0034", 10);
strlcpy (csuit, "Hearts", 10);
} else if (wplayercardsinhand[currentplayer][(cnp[2] - 1)] < 26) {
strlcpy (csuitcolour, "\0037", 10);
strlcpy (csuit, "Diamonds", 10);
} else if (wplayercardsinhand[currentplayer][(cnp[2] - 1)] < 39) {
strlcpy (csuitcolour, "\00314", 10);
strlcpy (csuit, "Clubs", 10);
} else {
strlcpy (csuitcolour, "\00315", 10);
strlcpy (csuit, "Spades", 10);
}
switch ((wplayercardsinhand[currentplayer][(cnp[2] - 1)] % 13)) {
case 12:
strlcpy (csuitcard, "Ace", 10);
break;
case 11:
strlcpy (csuitcard, "King", 10);
break;
case 10:
strlcpy (csuitcard, "Queen", 10);
break;
case 9:
strlcpy (csuitcard, "Jack", 10);
break;
default:
ircsnprintf(csuitcard, 10, "%d", ((wplayercardsinhand[currentplayer][(cnp[2] - 1)] % 13) + 2));
break;
}
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 played Cards\00311 %d , %d , %d \0039(%s %s of %s \0039)", wplayernick[currentplayer], cnp[0], cnp[1], cnp[2], csuitcolour, csuitcard, csuit);
for (wpln = 0; wpln < 3; wpln++) {
cnp[wpln]--;
wstackcards[wstackcardscurrent]= wplayercardsinhand[currentplayer][cnp[wpln]];
wstackcardscurrent++;
wplayerwarcardsplayed[currentplayer][wpln]= wplayercardsinhand[currentplayer][cnp[wpln]];
}
if (cnp[2] > cnp[0])
cnp[2]--;
if (cnp[2] > cnp[1])
cnp[2]--;
if (cnp[1] > cnp[0])
cnp[1]--;
for (wpln = 0; wpln < 3; wpln++) {
wplayercardstotal[currentplayer]--;
for (i = cnp[wpln]; i < wplayercardstotal[currentplayer]; i++) {
wplayercardsinhand[currentplayer][i]= wplayercardsinhand[currentplayer][(i +1)];
}
wplayercardsinhand[currentplayer][wplayercardstotal[currentplayer]]= 0;
}
currentplayer++;
if (currentplayer < currentwarplayercount) {
askplaycard();
} else {
checkwarwinner();
}
}
/*
* Player Plays Card
*/
void playcard(int cnp)
{
if ((cnp > 0) && (cnp < (wplayercardstotal[currentplayer] + 1))){
if (wplayercardsinhand[currentplayer][(cnp - 1)] < 13) {
strlcpy (csuitcolour, "\0034", 10);
strlcpy (csuit, "Hearts", 10);
} else if (wplayercardsinhand[currentplayer][(cnp - 1)] < 26) {
strlcpy (csuitcolour, "\0037", 10);
strlcpy (csuit, "Diamonds", 10);
} else if (wplayercardsinhand[currentplayer][(cnp - 1)] < 39) {
strlcpy (csuitcolour, "\00314", 10);
strlcpy (csuit, "Clubs", 10);
} else {
strlcpy (csuitcolour, "\00315", 10);
strlcpy (csuit, "Spades", 10);
}
switch ((wplayercardsinhand[currentplayer][(cnp - 1)] % 13)) {
case 12:
strlcpy (csuitcard, "Ace", 10);
break;
case 11:
strlcpy (csuitcard, "King", 10);
break;
case 10:
strlcpy (csuitcard, "Queen", 10);
break;
case 9:
strlcpy (csuitcard, "Jack", 10);
break;
default:
ircsnprintf(csuitcard, 10, "%d", ((wplayercardsinhand[currentplayer][(cnp - 1)] % 13) + 2));
break;
}
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 played Card\00311 %d \0039(%s %s of %s \0039)", wplayernick[currentplayer], cnp, csuitcolour, csuitcard, csuit);
cnp--;
wstackcards[wstackcardscurrent]= wplayercardsinhand[currentplayer][cnp];
wstackcardscurrent++;
wplayercardplayed[currentplayer]= wplayercardsinhand[currentplayer][cnp];
wplayercardstotal[currentplayer]--;
for (wpln = cnp; wpln < wplayercardstotal[currentplayer]; wpln++) {
wplayercardsinhand[currentplayer][wpln]= wplayercardsinhand[currentplayer][(wpln +1)];
}
wplayercardsinhand[currentplayer][wplayercardstotal[currentplayer]]= 0;
currentplayer++;
if (currentplayer < currentwarplayercount) {
askplaycard();
} else {
checkhandwinner();
}
}
}
/*
* Checks standard hand for a winner (not a war hand)
*/
2005-10-18 20:57:13 +00:00
static void checkhandwinner(void)
{
int i;
int hcnp = 0;
int hcnpt = 0;
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
if (warinprogress == wplayeratwar[wpln]) {
if ((wplayercardplayed[wpln] % 13) > hcnp) {
hcnp = (wplayercardplayed[wpln] % 13);
hcnpt = 1;
} else if ((wplayercardplayed[wpln] % 13) == hcnp) {
hcnpt++;
}
}
}
if (hcnpt == 1) {
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
if (warinprogress == wplayeratwar[wpln]) {
if ((wplayercardplayed[wpln] % 13) == hcnp) {
if (warinprogress == 1) {
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 wins the \0034WAR\0039.", wplayernick[wpln]);
} else {
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0039 takes the hand.", wplayernick[wpln]);
}
for (i = 0; i < wstackcardscurrent; i++) {
wplayercardsinhand[wpln][wplayercardstotal[wpln]]= wstackcards[i];
wplayercardstotal[wpln]++;
}
clearstack();
wpln= currentwarplayercount;
}
}
}
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
wplayeratwar[wpln]= 0;
}
warinprogress= 0;
} else {
irc_chanprivmsg (ws_bot, warroom, "\0034WAR DECLARED");
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
if (warinprogress == wplayeratwar[wpln]) {
wplayeratwar[wpln] = 0;
if ((wplayercardplayed[wpln] % 13) == hcnp) {
wplayeratwar[wpln]= 1;
if (wplayercardstotal[wpln] < 3) {
irc_chanprivmsg (ws_bot, warroom, "\0037%s\0038 Surrenders\0039 (Insufficient Cards)", wplayernick[wpln]);
hcnpt--;
removewar(wplayernick[wpln]);
if (currentwarplayercount < 2) {
wpln= currentwarplayercount;
return;
}
}
}
}
}
warinprogress= 1;
}
currentplayer= 0;
playershufflecards();
askplaycard();
}
/*
* copy war hand to normal for checking
*/
static void checkwarwinner(void)
{
int i;
for (wpln = 0; wpln < currentwarplayercount; wpln++) {
if (wplayeratwar[wpln] == 1) {
wplayercardplayed[wpln]= wplayerwarcardsplayed[wpln][2];
} else {
wplayercardplayed[wpln]= 0;
}
for (i = 0; i < 3; i++) {
wplayerwarcardsplayed[wpln][i]= 0;
}
}
checkhandwinner();
}
/*
* clears the stack
*/
2005-10-18 20:57:13 +00:00
static void clearstack(void) {
for (wpln = 0; wpln < 52; wpln++) {
wstackcards[wpln]= 0;
}
wstackcardscurrent= 0;
}