Logo Search packages:      
Sourcecode: yics version File versions  Download package

types.c

/*
 * YICS: Connect a FICS interface to the Yahoo! Chess server.
 * Copyright (C) 2004  Chris Howie
 *
 * 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "debug.h"
#include "globals.h"
#include "console.h"
#include "util.h"

char gameType(Table *table) {
      int etime;

      if (table == NULL)
            return '?';

      etime = tabletime(table) + (tableinc(table) * 2 / 3);

      if (etime == 0)   return 'u';
      if (etime <  3)   return 'l';
      if (etime < 15)   return 'b';
                  return 's';
}

char *strGameType(Table *table) {
      switch (gameType(table)) {
      case 'u':
            return "untimed";

      case 'l':
            return "lightning";

      case 'b':
            return "blitz";
      }

      return "standard";
}

Option *createOption(const char *key, const char *value) {
      Option *option = malloc(sizeof(Option));
      int keyl, valuel;

      if (option == NULL)
            return NULL;

      keyl = strlen(key) + 1;
      valuel = strlen(value) + 1;

      option->key = malloc(keyl);
      if (option->key == NULL) {
            free(option);
            return NULL;
      }

      option->value = malloc(valuel);
      if (option->value == NULL) {
            free(option->key);
            free(option);
            return NULL;
      }

      memcpy(option->key, key, keyl);
      memcpy(option->value, value, valuel);

      option->next = NULL;

#if MEMDEBUG
      option_count++;
#endif

      return option;
}

Option *setOption(Option *option, const char *key, const char *value) {
      char *tmp;

      if (option == NULL)
            return NULL;

      while (option) {
            if (!strcmp(key, option->key)) {
                  tmp = realloc(option->value, strlen(value) + 1);
                  if (tmp == NULL)
                        return NULL;
                  option->value = tmp;
                  strcpy(option->value, value);
                  break;
            }
            if (option->next == NULL) {
                  option->next = createOption(key, value);
                  option = option->next;
                  break;
            }
            option = option->next;
      }

      return option;
}

Option *destroyOption(Option *option) {
      Option *next;

      if (option == NULL)
            return NULL;

      next = option->next;

      free(option->key);
      free(option->value);
      free(option);

#if MEMDEBUG
      option_count--;
#endif

      return next;
}

void destroyOptions(Option *option) {
      while (option)
            option = destroyOption(option);
}

Option *findOption(Option *option, char *key) {
      while (option != NULL) {
            if (!strcmp(key, option->key))
                  return option;
            option = option->next;
      }

      return NULL;
}

long findOptionLong(Option *option, char *key) {
      while (option != NULL) {
            if (!strcmp(key, option->key))
                  return strtol(option->value, NULL, 10);
            option = option->next;
      }

      return 0;
}

String *StringNew(const char *content, int length) {
      String *str = malloc(sizeof(String));

      if (str == NULL)
            return NULL;

      if (length < 0)
            length = strlen(content);

      str->string = malloc(length + 1);
      if (str->string == NULL) {
            free(str);
            return NULL;
      }

      memcpy(str->string, content, length);
      str->string[length] = '\0';
      str->length = length;

#if MEMDEBUG
      string_count++;
#endif

      return str;
}

void StringFree(String *str) {
      if (str == NULL)
            return;

      if (str->string != NULL)
            free(str->string);

#if MEMDEBUG
      string_count--;
#endif

      free(str);
}

String *StringSet(String *str, const char *content, int length) {
      char *tmp;

      if (str == NULL)
            return NULL;

      if (length < 0)
            length = strlen(content);

      tmp = malloc(length + 1);
      if (tmp == NULL)
            return NULL;

      memmove(tmp, content, length);
      if (str->string)
            free(str->string);

      str->string = tmp;
      str->string[length] = '\0';
      str->length = length;

      return str;
}

String *StringCat(String *str, const char *cat, int length) {
      char *tmp;

      if ((str == NULL) || (cat == NULL))
            return NULL;

      if (length < 0)
            length = strlen(cat);

      tmp = realloc(str->string, str->length + length + 1);
      if (tmp == NULL)
            return NULL;
      str->string = tmp;

      memcpy(&str->string[str->length], cat, length);
      length += str->length;
      str->string[length] = '\0';
      str->length = length;

      return str;
}

void addMove(Game *s, Move *move) {
      Movelist *last = s->movelist;
      Movelist *new = malloc(sizeof(Movelist));

      if (new == NULL)
            return;

      new->move = *move;
      new->next = NULL;

      if (last == NULL) {
            s->movelist = new;
      } else {
            while (last->next != NULL)
                  last = last->next;
            last->next = new;
      }

      s->move = &new->move;
}

uchar addRepetition(Game *s) {
      Repetition *current = s->repetitions, *last = NULL, *new;

      while (current != NULL) {
            if ((current->tomove == s->turn) && !memcmp(current->position,
                        s->board, sizeof(Board)))
                  return ++(current->times);
            last = current;
            current = current->next;
      }

      new = malloc(sizeof(Repetition));
      if (new == NULL)
            return 0;

      memcpy(new->position, s->board, sizeof(Board));
      new->times = 1;
      new->tomove = s->turn;
      new->next = NULL;

      if (last != NULL)
            last->next = new;
      else
            s->repetitions = new;

      return 1;
}

void destroyMovelist(Game *s) {
      Movelist *current, *next;

      current = s->movelist;
      while (current != NULL) {
            next = current->next;
            free(current);
            current = next;
      }

      s->movelist = NULL;
}

void destroyRepetitions(Game *s) {
      Repetition *current, *next;

      current = s->repetitions;
      while (current != NULL) {
            next = current->next;
            free(current);
            current = next;
      }

      s->repetitions = NULL;
}

void initGame(Game *s) {
      int i, j;

      for (i = 0; i < 8; i++)
            for (j = 2; j < 6; j++)
                  s->board[i][j] = EMPTY;

      for (i = 0; i < 8; i++)
            s->board[i][1] = W_PAWN;

      for (i = 0; i < 8; i++)
            s->board[i][6] = B_PAWN;

      s->board[0][0] = W_ROOK;
      s->board[1][0] = W_KNIGHT;
      s->board[2][0] = W_BISHOP;
      s->board[3][0] = W_QUEEN;
      s->board[4][0] = W_KING;
      s->board[5][0] = W_BISHOP;
      s->board[6][0] = W_KNIGHT;
      s->board[7][0] = W_ROOK;
      s->board[0][7] = B_ROOK;
      s->board[1][7] = B_KNIGHT;
      s->board[2][7] = B_BISHOP;
      s->board[3][7] = B_QUEEN;
      s->board[4][7] = B_KING;
      s->board[5][7] = B_BISHOP;
      s->board[6][7] = B_KNIGHT;
      s->board[7][7] = B_ROOK;

      s->castlewa = s->castlewh = 1;
      s->castleba = s->castlebh = 1;
      s->dpush = -1;
      s->captured = EMPTY;
      s->halfmoves = 0;
      s->lastirrev = -1;
      s->turn = WHITE;
      s->move = NULL;
      s->movetime = gettimeofdayll();
      s->lastmove.present = false;

      destroyMovelist(s);
      destroyRepetitions(s);
}

void debugGame(Game *s, int number, char *msg, Move *move) {
      FILE *rlog = fopen("yics-error.txt", "a");

      int mnum = 1;
      bool mblack = 0;
      int x, y;
      Movelist *current;

      if (rlog == NULL)
            rlog = stdout;

      fprintf(rlog,
            "---ERROR REPORT---\n"
            "A fatal error has occured on table %d:\n"
            "    %s\n"
            "While trying to make the move:\n"
            "    (%d, %d) -> (%d, %d) = (%d)\n\n"

            "Please copy and paste this entire message into a bug report at\n"
            "http://www.yics.org/bugs.php\n\n"

            "Position at the time of the error:\n",

            number, msg, move->x1, move->y1, move->x2, move->y2, move->promoteTo);

      for (y = 7; y >= 0; y--) {
            for (x = 0; x < 8; x++) {
                  fprintf(rlog, "%02X", s->board[x][y]);
            }
            fprintf(rlog, "\n");
      }

      fprintf(rlog, "\nTable movelist:\n");

      current = s->movelist;
      while (current != NULL) {
            if (mblack) {
                  fprintf(rlog, "%s\n", current->move.alg);
                  mblack = 0;
                  mnum++;
            } else {
                  fprintf(rlog, "%3d. %-8s", mnum, current->move.alg);
                  mblack = 1;
            }

            current = current->next;
      }

      if (mblack) {
            fprintf(rlog, "\n");
      }

      fprintf(rlog, "---ERROR REPORT---\n");
      if (rlog != stdout) {
            fclose(rlog);
            sysiprint("\nA debug message was appended to a file named \"yics-error.txt\".  "
                  "Please copy the report from this file and paste it into a bug report at "
                  "http://www.yics.org/bugs.php .\n");
      }

      die("Chess logic error.");
}

Generated by  Doxygen 1.6.0   Back to index