Problem of the Day
A new programming or logic puzzle every Mon-Fri

Roaming Knight

You are given an 8 by 8 chess board with two randomly placed pieces. One of the pieces is a knight and the other piece is a King which does not move. Write a program to determine if the knight can capture the king in two moves or less. If you're unfamiliar with chess this article will show you how a knight moves.

Permalink: http://problemotd.com/problem/roaming-knight/

Comments:

  • Emre Ozdemir - 10 years, 6 months ago

    My solution with C++

    #include <iostream>
    using namespace std;
    
    struct increment {
        int x, y;
    };
    int i, g;
    const increment moves[8]= {{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
    bool checkMoves1(int x, int y, int a, int b)    // One move checker
    {
        for(i=0;i<8;i++)
            if(x+moves[i].x==a && y+moves[i].y==b)
                return 1;
    
        return 0;   
    };
    bool checkMoves2(int x, int y, int a, int b)    //Two move checker
    {
        int x2, y2, x3, y3;
        for(i=0;i<8;i++)    
        {
                x2 = x + moves[i].x;
                y2 = y + moves[i].y;
                for(g=0;g<8;g++)
                {
                    if(x2 + moves[g].x==a && y2 + moves[g].y==b)
                        return 1;
                }
        }
        return 0;   
    };
    
    int main(){
        int x, y, a, b, x2,y2;
        cout<<"Please enter Knight's place: ";
        cin>>x>>y;
        cout<<"Please enter King's place: ";
        cin>>a>>b;
        cout<<"\n";
    
        if(checkMoves1(x,y,a,b))
            cout<<"Knight can capture King with one move!";
    
        else
        {
            if(checkMoves2(x,y,a,b))
                    cout<<"Knight can capture King with two moves!";
            else
                cout<<"Can't capture";
        }
        getchar();
        getchar();
        return 0;
    }
    
    

    reply permalink

  • Kaan Genç - 10 years, 6 months ago

    Python 3.4. I kinda cheated by creating a list of possible moves. I used the "distance from f5 square" image from the linked article to build the list.

    from random import randrange
    
    def Locations(x, y):
        return [(x + 1, y + 2),#1 moves
                (x + 2, y + 1),
                (x + 2, y - 1),
                (x + 1, y - 2),
                (x - 1, y - 2),
                (x - 2, y - 1),
                (x - 1, y + 2),
                (x - 2, y + 1),
                (x + 1, y + 1),#corners
                (x + 1, y - 1),
                (x - 1, y + 1),
                (x - 1, y - 1),
                (x + 2, y + 0),#2 to the sides
                (x - 2, y + 0),
                (x + 0, y + 2),
                (x + 0, y - 2),
                (x - 3, y + 1),#3-1's
                (x - 3, y - 1),
                (x + 3, y + 1),
                (x + 3, y - 1),
                (x + 1, y + 3),
                (x - 1, y + 3),
                (x + 1, y - 3),
                (x - 1, y - 3),
                (x + 3, y + 3),#3-3's
                (x - 3, y - 3),
                (x + 3, y - 3),
                (x - 3, y + 3),
                (x + 4, y + 0),#4 to the sides
                (x - 4, y + 0),
                (x + 0, y + 4),
                (x + 0, y - 4),
                (x + 4, y + 2),#4-2's
                (x - 4, y + 2),
                (x + 4, y - 2),
                (x - 4, y - 2),
                (x + 2, y + 4),
                (x + 2, y - 4),
                (x - 2, y + 4),
                (x - 2, y - 4)]
    
    def CanReach(knight, king):
        xKnight, yKnight = knight
        xKing, yKing = king
        locations = Locations(xKnight, yKnight)
        for x, y in locations:
            if ((x, y) == (xKing, yKing)):
                return True
        return False
    
    #Generate unique locations for King and Knight
    xKnight = randrange(8)
    yKnight = randrange(8)
    xKing = randrange(8)
    yKing = randrange(8)
    while (xKnight == xKing and yKnight == yKing):
        xKing = randrange(8)
        yKing = randrange(8)
    print("Knight: x:{} y:{}\n"
          "King: x:{} y:{}".format(xKnight, yKnight, xKing, yKing))
    #Get the list of locations Knight can reach in two moves
    if (CanReach((xKnight, yKnight), (xKing, yKing))):
        print("The Knight can reach the King.")
    else:
        print("The Knight can NOT reach the King.")
    

    reply permalink

  • keemz - 10 years, 6 months ago

    For practice, here is the code written in Apple's new Swift:

    
    
    class Tile {
        var row = 0
        var col = 0
        init(row: Int, col: Int) {
            self.row = row
            self.col = col
        }
    
        func equals(tile: Tile) -> Bool {
            return (self.row == tile.row && self.col == tile.col)
        }
    }
    
    class Piece {
        var position : Tile
    
        init(row:Int, col:Int) {
            self.position = Tile(row: row, col: col)
        }
    }
    
    class Knight : Piece {
    
        var moves = [
            [1,2],
            [2,1],
            [-1,2],
            [2,-1],
            [-2,1],
            [1,-2],
            [-1,-2],
            [-2,-1]
            ]
    
        func getMoves() -> Array<Tile> {
            var tiles = Array<Tile>()
    
            for move in moves {
                var tile : Tile = possibleTileForRow(move[0], col: move[1])
                if tile.row != -1 {
                    tiles.append(tile)
                }
            }
            return tiles
        }
    
        func possibleTileForRow(row :Int, col: Int) -> Tile {
            var aTile : Tile
            if (self.position.row + row < 8 && self.position.row + row > -1 && self.position.col + col < 8 && self.position.col + col > -1) {
                return Tile(row: self.position.row + row, col: self.position.col + col)
            }
            return Tile(row: -1, col: -1)
        }
    }
    
    var king: Piece = Piece(row: 3, col: 7)
    var knight: Knight = Knight(row: 2, col:4 )
    
    var moves = knight.getMoves()
    
    var found = false
    for move in moves {
        move
        if move.equals(king.position) {
            found = true
            break;
        }
    
        knight.position = move
        var newMoves = knight.getMoves()
        for newMove in newMoves {
            newMove
            king.position
            if newMove.equals(king.position) {
                found = true
                break
            }
        }
    
        if found {
            break
        }
    }
    
    if found {
        print("kill!")
    }
    
    

    reply permalink

  • keemz - 10 years, 6 months ago

    break without semi-colon

    reply permalink

  • Max Burstein - 10 years, 6 months ago

    Very cool!

    reply permalink

Content curated by @MaxBurstein