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

turno.c

Go to the documentation of this file.
/*    $Id: turno.c,v 1.37 2002/09/09 03:52:07 riq Exp $     */
/* Tenes Empanadas Graciela
 *
 * Copyright (C) 2000 Ricardo Quesada
 *
 * Author: Ricardo Calixto Quesada <rquesada@core-sdi.com>
 *
 * 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; only version 2 of the License
 *
 * 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.
 */
/**
 * @file turno.c
 * Manejo de turnos
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "server.h"


#undef DEBUG_TURNO

#ifdef DEBUG_TURNO
# define TURNO_DEBUG(x...) PDEBUG(x)
#else
# define TURNO_DEBUG(x...)
#endif

/* Gives turn to the next player */
00041 TEG_STATUS turno_2nextplayer( PSPLAYER *ppJ )
{
      PSPLAYER pJ;
      PLIST_ENTRY first_node = (PLIST_ENTRY)*ppJ;
      PLIST_ENTRY l = LIST_NEXT( (*ppJ));

      TURNO_DEBUG("Old turn: '%s'\n",(*ppJ)->name);

      g_game.old_turn = *ppJ;

      if( IsListEmpty( first_node ) )
            return TEG_STATUS_ERROR;

      while( l != first_node )  {
            pJ = (PSPLAYER) l;
            if( (l != &g_list_player) && player_is_playing(pJ) ) {
                  (*ppJ) = pJ;
                  TURNO_DEBUG("New turn: '%s'\n",pJ->name);
                  return TEG_STATUS_SUCCESS;
            }
            l = LIST_NEXT(l);
      }

      con_text_out_wop(M_ERR,"Abnormal error in turno_2nextplayer\n");
      return TEG_STATUS_PLAYERNOTFOUND;
}

/**
 * @fn TEG_STATUS turno_2prevplayer( PSPLAYER *ppJ )
 * Gives turn to the previous player (used when the a player leaves the game)
 */
#if 0
TEG_STATUS turno_2prevplayer( PSPLAYER *ppJ )
{
      PSPLAYER pJ;
      PLIST_ENTRY first_node = (PLIST_ENTRY)*ppJ;
      PLIST_ENTRY l = LIST_PREV( (*ppJ));

      TURNO_DEBUG("Old turn: '%s'\n",(*ppJ)->name);

      g_game.old_turn = *ppJ;

      if( IsListEmpty( first_node ) )
            return TEG_STATUS_ERROR;

      while( l != first_node ) {
            pJ = (PSPLAYER) l;
            if( (l != &g_list_player) && player_is_playing(pJ) ) {
                  (*ppJ) = pJ;
                  TURNO_DEBUG("New turn: '%s'\n",pJ->name);
                  return TEG_STATUS_SUCCESS;
            }
            l = LIST_PREV(l);
      }

      con_text_out_wop(M_ERR,"Abnormal error in turno_2prevplayer\n");
      return TEG_STATUS_PLAYERNOTFOUND;
}
#endif

/* Ends the player turn */
00102 TEG_STATUS turno_end( PSPLAYER pJ )
{
      assert(pJ);

      /* FIXME: Creo que igual este chequeo no sirve, porque se chequea cuando
       * se conquista un country. Solo sirve si uno gana sin conquistar algun country
       * Puede pasar ???
       */
      if( mission_chequear( pJ ) == TEG_STATUS_GAMEOVER ) {
            game_end( pJ );
            return TEG_STATUS_GAMEOVER;
      }

      player_clear_turn( pJ );
      return TEG_STATUS_SUCCESS;
}

/* Gives turn to the next player */
00120 TEG_STATUS turno_next( void )
{
      assert(g_game.turno);

      /* give turn to the next one */
      if( turno_2nextplayer( &g_game.turno ) == TEG_STATUS_SUCCESS ) {

            /* the one who has the turn is the one that started ? */
            if( turno_is_round_complete() ) {

                  turno_initialize_new_round();

                  aux_token_fichasc( g_game.turno );

            } else {
                  g_game.turno->estado = PLAYER_STATUS_ATAQUE;
                  netall_printf( TOKEN_TURNO"=%d\n",g_game.turno->numjug);
            }
            return TEG_STATUS_SUCCESS;
      }

      return TEG_STATUS_ERROR;
}

/* initializes the round. Called before the game starts */
00145 TEG_STATUS turno_init(void)
{
      int i;
      int real_i;
      PSPLAYER j;

      i = RANDOM_MAX(0,g_game.playing-1);

      player_from_indice( i , &real_i );
      if( player_whois( real_i, &j) != TEG_STATUS_SUCCESS )
            return TEG_STATUS_ERROR;

      g_game.old_turn = NULL;
      g_game.turno = j;
      g_game.empieza_turno = j;

      return TEG_STATUS_SUCCESS;
}

/* return true if the round is complete */
00165 BOOLEAN turno_is_round_complete()
{
      /* I want to know if the round is over. It is not enought to know 
       * if newturn == started because if a player with the turn exit the game
       * he will never receive the turn again, but the started turn will point 
       * to him 
       */
      PSPLAYER pJ;
      PLIST_ENTRY l;
      PLIST_ENTRY first_node;

      if( g_game.old_turn == NULL )
            return FALSE;

      if( g_game.empieza_turno == g_game.turno )
            return TRUE;

      /*
       * if the previous playing player of 'empieza turn' is 'old turn' then
       * the round is over
       */
      first_node = (PLIST_ENTRY) g_game.old_turn;
      l = LIST_NEXT( first_node );


      while( l != first_node )  {
            pJ = (PSPLAYER) l;
            if( (l != &g_list_player) && pJ->is_player ) {
                  if( pJ == g_game.empieza_turno )
                        return TRUE;
                  else if( pJ == g_game.turno )
                        return FALSE;
            }
            l = LIST_NEXT(l);
      }

      /* abnormal error */
      fprintf(stderr,"Abnormal error in turno_is_round_complete()\n");
      return FALSE;
}

/* initialize variables for the new round */
00207 void turno_initialize_new_round( void )
{
      PLIST_ENTRY l = g_list_player.Flink;
      PSPLAYER pJ;

      /* So, a new round is started */
      turno_2nextplayer( &g_game.empieza_turno );
      g_game.turno = g_game.empieza_turno;

      g_game.round_number++;

      /* add the continents that it defend */
      while( !IsListEmpty( &g_list_player ) && (l != &g_list_player) )
      {
            unsigned long conts;
            pJ = (PSPLAYER) l;

            l = LIST_NEXT(l);

            if( pJ->is_player ) {
                  if( player_listar_conts( pJ, &conts ) == TEG_STATUS_SUCCESS ) {
                        int i;
                        for(i=0;i<CONT_CANT;i++)
                        {
                              if( conts & 1 )
                                    pJ->player_stats.continents_turn[i]++;
                              conts >>= 1;
                        }
                  }

                  /* update the score */
                  stats_score( &pJ->player_stats );
            }
      }
      
      netall_printf( TOKEN_NEW_ROUND"=%d,%d\n",g_game.turno->numjug, g_game.round_number );

}

Generated by  Doxygen 1.6.0   Back to index