HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Shortest knight path

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
pathknightshortest

Problem

In preparing a review of this question, I decided to rewrite the code from scratch using a more object oriented approach as I suggested in my review.

To recapitulate the problem statement, we are given an input such as the following:

6 5
. s . . .
. d . . .
. . x . .
. . x . .
. . . . .
. . . . .


The two integers are the number of rows and columns respectively, and the lines that follow are the board to be examined. A knight is placed at starting point s and must travel to the destination at d without landing on any occupied squares (denoted by x). Open squares are marked with . and whitespace must separate each square in the input.

The output of the program is the minimum number of valid knight moves to get from s to d or the word "NO" if there is no path. The search uses a simple breadth first search. Each call to validMoves generates a std::vector of all unvisited squares that can be reached with one move of a knight originating on any of the squares indicated in the input std::vector moves.

The algorithm terminates when either there are no valid moves left or a path has been found to the destination.

I'm interested in a general review, but in particular, the repeated calls to tryMove() seem somewhat inelegant to me, but I didn't come up with anything that I thought was better.

knight.cpp

```
#include
#include
#include
#include

class Board
{
public:
Board(int n, int m) :
start{ERR},
finish{ERR},
rows{n},
cols{m},
map{new char[rows*cols]}
{}
virtual ~Board() { delete[] map; }
int mindistance() const {
if (finish == ERR || start == ERR) {
return ERR;
}
return measure(start, finish);
}
friend std::istream& operator>>(std::istream& in, Board &b) {
int a = 0;
for (int i = b.rows; i; --i) {
for (int j = b.cols; j; --j, ++a) {
in >> b.map[a];
switch(b.map[a]) {

Solution

-
A standard way to loop over a regular set of moves is to prepare an array of deltas:

using square = std::pair;
    std::vector deltas = {
        {1, 2}, {1, -2}, {-1, 2}, {-1, -2},
        {2, 1}, {2, -1}, {-2, 1}, {-2, -1}
    };

    for (auto delta: deltas) {
        tryMove(x + delta.first, y + delta.second);
    }


-
It feels that std::pair generally represents a square better than a single integer.

Code Snippets

using square = std::pair<int, int>;
    std::vector<square> deltas = {
        {1, 2}, {1, -2}, {-1, 2}, {-1, -2},
        {2, 1}, {2, -1}, {-2, 1}, {-2, -1}
    };


    for (auto delta: deltas) {
        tryMove(x + delta.first, y + delta.second);
    }

Context

StackExchange Code Review Q#119901, answer score: 2

Revisions (0)

No revisions yet.