1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
#include <iostream>
using namespace std;
const int n = 8 ;
using board_type = bool[n][n] ;
//The way we're going to solve the problem of describing which moves a Knight
//can make from a certain position is to create an 8x8 board of booleans.
//A square that says true means the knight could move there. False means that
//the knight cannot move there.
//The clear function sets every square to false. This gives us a good starting
//state. If we start with a clear board, we can later go mark the specific squares
//that a knight is allowed to move to.
void clear( board_type& board )
{
for( auto& row : board )
{
for( auto& v : row )
{
v = false;
}
}
}
//We are going to use some math to determine which squares are possible destinations
//for a knight. We're going to move over 2 rows and 1 column, OR 1 row and 2 columns.
//What if we're in column 0 and try to move over to column -1? That's not valid.
//We must do some bounds-checking. That's what this function is for. It will only
//attempt to set a square to 'true' if it falls within legal bounds for a board.
void set_if_valid( board_type& board, int row, int column )
{
if( row >= 0 && row < n && column >= 0 && column < n )
{
board[row][column] = true ;
}
}
//This function takes a board, clears it so that everything says false, then manually
//calculates which squares are valid destinations for a knight whose current position is
//specified by the 'row' and 'column' parameters.
void possible_knight_moves( board_type& board, int row, int column )
{
clear(board) ; //set everything on the board to false
//check that row and column denote a legal cell on the board
if( row >= 0 && row < n && column >= 0 && column < n)
{
//In many math and science fields, 'delta' is commonly used as a synonym for
//'amount of change'. Hence, row_delta = 2 means change the row by two and
//column_delta = 1 means change the column by 1. + and - indicate the direction
//of change.
//in these two loops (one nested in the other) we're going to specify all the moves
//that can happen when we move over TWO rows (in either direction, hence +2 AND -2)
//and move over ONE column (also in either direction)
//That's 4 different moves covered by this part.
for( const int row_delta : { -2, +2 } )
{
for( const int column_delta : { -1, +1 } )
{
set_if_valid( board, row + row_delta, column + column_delta );
}
}
//in these two loops, now we're going to specify all the moves that can happen when
//we move over ONE row and TWO columns. Notice that this is the opposite of the last loops.
//Again, that's 4 different moves covered in this part.
for( const int row_delta : { -1, +1 } )
{
for( const int column_delta : { -2, +2 } )
{
set_if_valid( board, row + row_delta, column + column_delta );
}
}
}
else cout<< "Wrong coordination" <<endl;
}
int main()
{
board_type board {} ;
int row = 0;
int column = 0 ;
cin >> row;
cout << endl;
cin >> column ;
possible_knight_moves( board, row, column ) ;
for( int row = 0 ; row < n ; ++row ) for( int column = 0 ; column < n ; ++column )
{ if( board[row][column] ) cout << row << ", " << column << '\n' ; }
}
|