User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C section within the Software Development category of DaniWeb, a massive community of 402,955 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,854 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C advertiser: Programming Forums

Horse Game

Join Date: May 2008
Location: Infinite Castle, below Beltline
Posts: 282
Reputation: Prabakar is an unknown quantity at this point 
Rep Power: 1
Solved Threads: 22
Prabakar's Avatar
Prabakar Prabakar is offline Offline
Posting Whiz in Training

Re: Horse Game

  #9  
May 3rd, 2008
I have never used bios.h much but I hope bioskey(1) will work the same way as kbhit()

#include<stdlib.h>
#include <stdio.h>
#include <bios.h>
#include<string.h>

/* Defination of all moves */
#define TL 0x01 // top left i.e., 2 squares up & 1 square left
#define TR 0x02
#define RT 0x04
#define RB 0x08
#define BR 0x10
#define BL 0x20
#define LB 0x40
#define LT 0x80

// stack which holds the position
typedef struct visited {
  char place ; // varies from  0 to 63 representing a square
  char moves ; // availabe moves -> every bit represents a possible move
  struct visited *next ; // link to previous move
} VISIT ;

VISIT *head ; // contains the latest move made by the horse

#define removMov(mov) head->moves &= ~(mov) // removes an available move
#define isMove(mov) (head->moves&(mov))	   // checks if the move is available

unsigned int number = 0 ; // number of answers written in the current file
unsigned int fno = 0 ;    // file number

int count ; // number of places the horse has covered at any point

FILE *sol ; /* pointer to the file in which the answer is written
	"SOLXXXXX.txt" where XXXXX is an unsigned integer  */

void newPlace    ( char ) ;// pushes a new move to the stack VISIT
void undo        ( void ) ;// pops the stack i.e., undos the last move
char isKnown     ( char ) ;// checks if a place has been visited by the horse
void copystack   ( void ) ;// copies the answer to the sol file
void initProg    ( void ) ;// resumes from previous run
char availability( char ) ;// checks if it is possible to move to a square

void newPlace ( char place ) {// push onto the stack
  struct visited *new ;
  new = ( VISIT * ) malloc ( sizeof ( VISIT ) ) ;
  new -> place = place ;
  new -> moves = availability ( place ) ;	// compute availability and store
  new -> next = head ;
  head = new ;
  count ++ ;		// increment count, as a new move has been made
}

void undo ( ) { // pops the stack
  VISIT *temp ;
  if ( head == NULL ) // check if the stack is already empty
    return ;
  temp = head ;
  head = head -> next ;
  free ( temp ) ;
  count -- ;   		// decrement count
}

char isKnown ( char place ) {
  VISIT *temp = head ;
  while ( temp ) { // surf through the stack to check if the place is visited
    if ( temp -> place == place ) return 1 ;
    temp = temp -> next ;
  }
  return 0 ; // executes only if place is not found
}

void copystack ( void ) { // executes when an answer is found
  char move[64], i ;  // to store the moves in order
  VISIT *temp = head ;

  for ( i = 63 ; i >= 0 ; i-- ) {
    move[i] = temp -> place ;
    temp = temp -> next ;
  }

  for ( i = 0 ; i < 64 ; i++ )
    fprintf ( sol, "%d ", move[i] ) ;
  fprintf ( sol, "\n" ) ;
}

void initProg ( ) {
  FILE *recover ;
  count = 0 ;
  head = NULL ;
  
  recover = fopen ( "Recover.txt", "rt" ) ;
/*
	this file contains the no of last file opened say 1 (for sol1.txt)
	number of answers stored in this file
	count of the moves that are to be in the stack
	data that are to be stored in the stack
*/
  if ( recover != NULL ) {
    char temp[10], fname[15] = "Sol", i, j ; // initialize fname
    fscanf ( recover, "%u %u %d", &fno, &number, &count ) ;

  // This block opens the last file created by the application
    itoa ( fno, temp, 10 ) ;
    strcat ( fname, temp ) ; // add sufix
    strcat ( fname, ".txt" ) ; // add extenstion
    sol = fopen ( fname, "a+" ) ; // open the fname

    for ( i = 0 ; i < count ; i ++ ) {
    // This block resumes the movements made
      VISIT *new ;
      int p, m ;
      fscanf ( recover, "%d %d", &p, &m ) ; // data of a node
  // push the data on to the stack
      new = ( VISIT * ) malloc ( sizeof ( VISIT ) ) ;
      new -> place = p ;
      new -> moves = m ;
      new -> next = head ;
      head = new ;
    }
    fclose ( recover ) ;
  }
  else { // start from scrach
    sol = fopen ( "SOL0.TXT", "wt" ) ;
    newPlace ( 0 ) ; // place the horse in the top left corner on the board
  }
  puts ( "\n Press Space or Esc or Enter Key to pause after next result" ) ;
  puts ( " \n Program will resume on next run with the help of recover.txt" ) ;
  printf ( "\n File No: %u Solution No: %-5u", fno, number ) ;
}

// saves the current state in recover.txt
void savestate ( ) {
  FILE *recover ;
  char i, m[64], p[64], c ;
  recover = fopen ( "Recover.txt", "wt" ) ;
  // stores the file no, no of answers writen & count of moves in stack
  fprintf ( recover, " %u %u %d ", fno, number, c=count );
 // stores the moves in reverse order for ( LIFO of stack )
  for ( i = count-1 ; i>-1 ; i-- ) {
    p[i] = head->place;
    m[i] = head->moves;
    undo();
  }
	// stores data in file
  for ( i = 0; i < c ; i++ )
    fprintf ( recover, "\n %d %d",(int) p[i],(int) m[i] ) ;
  fclose ( recover ) ;
}

main ( ) {
  char filename[15] = "sol", temp[10] ;
  void savestate ( void ) ;
  initProg ( ) ;
  while ( head ) { 		// till the horse has no where left to go
    char moves, c ; 	// c checks user input
    if ( count == 64 ) { // if an answer is found
      number ++ ;
      // increment the number of answer in the current file
      copystack ( ) ;
      // save to file
      printf ( "\rFile No: %u Solution No: %-5u", fno, number ) ;
      // update screen
     if ( number == 0x8000 ) { // if 0x8000 answers are writen goto next file
	// Creates a unique file name on which the next result will be stored

        number = 0 ;
        // reset number of answers in the new file
        fclose ( sol ) ;
        // close the old file & open a new one
        itoa( ++fno, temp , 10)  ;
        strcat ( filename, temp ) ;
        strcat ( filename, ".txt" ) ;
        sol = fopen ( filename, "wt" ) ;
        printf ( "\a" ); // to notify that a multiple of 0x8000 answers have been found
      }
      if ( bioskey(1)) {// if user want to stop the prg then save its state
        c = bioskey ( 0 ) ;
        if ( c == ' ' || c == '\x1B' || c == '\r' || c == '\n' )
	savestate () ;
      }
    }
   // Move horse if there is an availability
    if ( isMove ( TL ) ) {
      removMov ( TL ) ;
      newPlace ( head->place - 17 ) ;
    }
    else if ( isMove ( TR ) ) {
      removMov ( TR ) ;
      newPlace ( head->place - 15 ) ;
    }
    else if ( isMove ( RT ) ) {
      removMov ( RT ) ;
      newPlace ( head->place - 6 ) ;
    }
    else if ( isMove ( RB ) ) {
      removMov ( RB ) ;
      newPlace ( head->place + 10 ) ;
    }
    else if ( isMove ( BR ) ) {
      removMov ( BR ) ;
      newPlace ( head->place + 17 ) ;
    }
    else if ( isMove ( BL ) ) {
      removMov ( BL ) ;
      newPlace ( head->place + 15 ) ;
    }
    else if ( isMove ( LB ) ) {
      removMov ( LB ) ;
      newPlace ( head->place + 6 ) ;
    }
    else if ( isMove ( LT ) ) {
      removMov ( LT ) ;
      newPlace ( head->place - 10 ) ;
    }
    else undo ( ) ;
  }
}

char availability ( char place )  {
  char moves = 0 ;
   /*Check Boundary condition*/  /*Check if visited*/
  if( place % 8!=0 && place >15 && !isKnown( place - 17))
    moves |= TL ;
  if( place % 8!=7 && place >15 && !isKnown( place - 15))
    moves |= TR ;
  if( place % 8<=5 && place >7  && !isKnown( place - 6 ))
     moves |= RT ;
  if( place % 8>=2 && place >7  && !isKnown( place - 10))
     moves |= LT ;
  if( place % 8!=0 && place <48 && !isKnown( place + 15))
    moves |= BL ;
  if( place % 8!=7 && place <48 && !isKnown( place + 17))
    moves |= BR ;
  if( place % 8>=2 && place <56 && !isKnown( place + 6 ))
    moves |= LB ;
  if( place % 8<=5 && place <56 && !isKnown( place + 10))
    moves |= RB ;
/* The following may lead to losing some answers
             but it speeds up the process!!*/
/* If the horse is near to the corner then visit the corner since there are just 2 ways to reach a corner '1 way in 1 way out'.*/
	switch ( place ) {
	case 41: if ( !isKnown( 56 ) ) moves &= BL ; break ;
	case 50: if ( !isKnown( 56 ) ) moves &= LB ; break ;
	case 53: if ( !isKnown( 63 ) ) moves &= RB ; break ;
	case 46: if ( !isKnown( 63 ) ) moves &= BR ; break ;
	case 13: if ( !isKnown( 07 ) ) moves &= RT ; break ;
	case 22: if ( !isKnown( 07 ) ) moves &= TR ; break ;
	}
	return moves ;
}
Reply With Quote  
All times are GMT -4. The time now is 6:39 pm.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC