added 4wins game
[NeonServV5.git] / src / modules / NeonFun.mod / game_4wins.c
diff --git a/src/modules/NeonFun.mod/game_4wins.c b/src/modules/NeonFun.mod/game_4wins.c
new file mode 100644 (file)
index 0000000..88503a1
--- /dev/null
@@ -0,0 +1,212 @@
+/* game_4wins.c - NeonServ v5.4
+ * Copyright (C) 2011-2012  Philipp Kreil (pk910)
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>. 
+ */
+#include "../module.h"
+#include "game_4wins.h"
+#include "bot_NeonFun.h"
+#include "../../IRCParser.h"
+#include "../../bots.h"
+#include "../../UserNode.h"
+#include "../../ChanUser.h"
+#include "../../tools.h"
+#include "../botid.h"
+
+struct fourwins_game *fourwins_active_games = NULL;
+
+int fourwins_next_free_y(struct fourwins_game *game, int x) {
+    int y;
+    for(y = 0; y < FOURWINS_MATRIX_HEIGHT; y++) {
+        if(!game->matrix[x][y].field)
+            return y;
+    }
+    return -1;
+}
+
+int fourwins_check_win(struct fourwins_game *game, int x, int y) {
+    int field = game->matrix[x][y].field;
+    if(!field) return 0;
+    //horizontal
+    {
+        int fc = 0;
+        int i;
+        for(i = x; i < FOURWINS_MATRIX_WIDTH; i++) {
+            if(game->matrix[i][y].field == field)
+                fc++;
+            else
+                break;
+        }
+        for(i = x-1; i >= 0; i--) {
+            if(game->matrix[i][y].field == field)
+                fc++;
+            else
+                break;
+        }
+        if(fc >= 4) return 1;
+    }
+    //senkrecht
+    if(y >= 3) {
+        int fc = 0;
+        int i;
+        for(i = y; i >= 0; i--) {
+            if(game->matrix[i][y].field == field)
+                fc++;
+            else
+                break;
+        }
+        if(fc >= 4) return 1;
+    }
+    //diagonal 1
+    {
+        int fc = 0;
+        int ix, iy;
+        for(ix = x, iy = y; ix < FOURWINS_MATRIX_WIDTH && iy < FOURWINS_MATRIX_HEIGHT; ix++, iy++) {
+            if(game->matrix[ix][iy].field == field)
+                fc++;
+            else
+                break;
+        }
+        for(ix = x, iy = y; ix >= 0 && iy >= 0; ix--, iy--) {
+            if(game->matrix[ix][iy].field == field)
+                fc++;
+            else
+                break;
+        }
+        if(fc >= 4) return 1;
+    }
+    //diagonal 2
+    {
+        int fc = 0;
+        int ix, iy;
+        for(ix = x, iy = y; ix < FOURWINS_MATRIX_WIDTH && iy >= 0; ix++, iy--) {
+            if(game->matrix[ix][iy].field == field)
+                fc++;
+            else
+                break;
+        }
+        for(ix = x, iy = y; ix >= 0 && iy < FOURWINS_MATRIX_HEIGHT; ix--, iy++) {
+            if(game->matrix[ix][iy].field == field)
+                fc++;
+            else
+                break;
+        }
+        if(fc >= 4) return 1;
+    }
+    return 0;
+}
+
+void fourwins_show_matrix(struct fourwins_game *game) {
+    int x,y;
+    char lineBuf[MAXLEN];
+    int linePos = 0;
+    for(x = 0; x < FOURWINS_MATRIX_WIDTH; x++) {
+        linePos += sprintf(lineBuf+linePos, (x ? "| %d " : " %d "), x+1);
+    }
+    fourwins_reply(game, lineBuf);
+    for(y = FOURWINS_MATRIX_HEIGHT-1; y >= 0; y--) {
+        linePos = 0;
+        for(x = 0; x < FOURWINS_MATRIX_WIDTH; x++) {
+            char *field = " ";
+            if(game->matrix[x][y].field == 1)
+                field = "\0034o\003";
+            if(game->matrix[x][y].field == 2)
+                field = "\00312o\003";
+            linePos += sprintf(lineBuf+linePos, (x ? " (%s)" : "(%s)"), field);
+        }
+        fourwins_reply(game, lineBuf);
+    }
+}
+
+TIMEQ_CALLBACK(fourwins_timeout) {
+    struct fourwins_game *game = data;
+    game->timer = NULL;
+    fourwins_reply(game, "NF_4WINS_TIMEOUT");
+    fourwins_free_game(game);
+}
+
+void fourwins_free_game(struct fourwins_game *game) {
+    struct fourwins_guest *guest, *next_guest;
+    for(guest = game->guests; guest; guest = next_guest) {
+        next_guest = guest->next;
+        free(guest);
+    }
+    struct fourwins_game *cgame, *prev = NULL;
+    for(cgame = fourwins_active_games; cgame; cgame = cgame->next) {
+        if(cgame == game) {
+            if(prev)
+                prev->next = game->next;
+            else
+                fourwins_active_games->next = game->next;
+        } else
+            prev = cgame;
+    }
+    free(game);
+}
+
+void fourwins_event_part(struct ChanUser *chanuser) {
+    struct fourwins_game *game;
+    for(game = fourwins_active_games; game; game = game->next) {
+        if(game->player[0] == chanuser || game->player[1] == chanuser) {
+            fourwins_reply(game, "NF_4WINS_GAME_CLOSED");
+            fourwins_free_game(game);
+            return;
+        }
+        struct fourwins_guest *guest, *prev_guest = NULL;
+        for(guest = game->guests; guest; guest = guest->next) {
+            if(guest->chanuser == chanuser) {
+                if(prev_guest)
+                    prev_guest->next = guest->next;
+                else
+                    game->guests = guest->next;
+                free(guest);
+                break;
+            } else
+                prev_guest = guest;
+        }
+    }
+}
+
+void fourwins_event_quit(struct UserNode *user) {
+    struct fourwins_game *game;
+    for(game = fourwins_active_games; game; game = game->next) {
+        if(game->player[0]->user == user || game->player[1]->user == user) {
+            fourwins_reply(game, "NF_4WINS_GAME_CLOSED");
+            fourwins_free_game(game);
+            return;
+        }
+        struct fourwins_guest *guest, *prev_guest = NULL;
+        for(guest = game->guests; guest; guest = guest->next) {
+            if(guest->chanuser->user == user) {
+                if(prev_guest)
+                    prev_guest->next = guest->next;
+                else
+                    game->guests = guest->next;
+                free(guest);
+                break;
+            } else
+                prev_guest = guest;
+        }
+    }
+}
+
+void fourwins_event_freechan(struct ChanNode *chan) {
+    struct fourwins_game *game;
+    for(game = fourwins_active_games; game; game = game->next) {
+        if(game->player[0]->chan == chan) {
+            fourwins_free_game(game);
+            return;
+        }
+    }
+}