棋盘的ASCII表示

时间:2014-07-12 12:46:29

标签: java ascii chess ascii-art

我正在用Java编写国际象棋引擎,我想用ASCII字符打印电路板(即:#为空方,K为国王,Q为皇后等)。代表应该区分黑色和白色片段。

我正在寻找输入Pieces列表(或地图或数组)的方法,并输出代表棋盘的字符串。

我已经有一个Board对象,包含一个Pieces列表。 Piece是一个抽象类,有一个位置(x,y)和一个颜色(黑色或白色)。然后King,Queen,Knight是实施Piece类的课程。

由于

3 个答案:

答案 0 :(得分:1)

首先:如果你打算写一个国际象棋引擎,那么你应该全面阅读Chess Programming Wiki

如果你仍然想尝试一下,你应该意识到面向对象编程的通常最佳实践可能不一定适用于国际象棋编程。 OOP的许多方面都瞄准了国际象棋根本不存在的目标。例如,可扩展性。你永远不会有其他作品,除了那些从一开始就存在的作品。对于高效的国际象棋引擎,您可能根本不会以类的形式使用这些片段的显式表示。对于董事会而言,您宁愿不使用List<Piece>,而是使用特殊数组(请参阅Board Representation了解很多(很多!)详细信息。)

但是,根据您当前的描述,似乎没有办法区分这些部分,除了通过instanceof检查检查他们的课程。当然,这不是很好,但除非你用Piece方法扩展getType()类(使整个继承无用),否则几乎没有其他选择。

我在下面概述了这种方法。符号大致基于algebraic move notation:字母

K = King
Q = Queen
B = Bishop
N = Knight
R = Rook
P = Pawn

通常用于表示碎片的类型。为了区分黑色和白色碎片,您可以使用大写字母表示白色碎片,使用小写字母表示黑色碎片。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class ChessBoardString
{
    public static void main(String[] args)
    {
        Board board = new Board();
        String s = createString(board);
        System.out.println(s);
    }

    private static String createString(Board board)
    {
        char empty = '.';
        char chars[] = new char[8*8+8];
        Arrays.fill(chars, empty);
        for (int y=0; y<8; y++)
        {
            chars[y*9+8] = '\n';
        }
        List<Piece> pieces = board.getPieces();
        for (Piece piece : pieces)
        {
            int x = piece.getX();
            int y = piece.getY();
            char c = charFor(piece);
            chars[x+y*9] = c;
        }
        String s = new String(chars);
        return s;
    }

    private static char charFor(Piece p)
    {
        char c = ' ';
        if (p instanceof King)
        {
            c = 'k';
        }
        else if (p instanceof Queen)
        {
            c = 'q';
        }
        else if (p instanceof Bishop)
        {
            c = 'b';
        }
        else if (p instanceof Knight)
        {
            c = 'n';
        }
        else if (p instanceof Rook)
        {
            c = 'r';
        }
        else if (p instanceof Pawn)
        {
            c = 'p';
        }
        if (p.getColor() == Color.WHITE)
        {
            c = Character.toUpperCase(c);
        }
        return c;
    }
}



class Board
{
    List<Piece> getPieces()
    {
        List<Piece> pieces = new ArrayList<Piece>();
        pieces.add(new King(Color.WHITE,3,4));
        pieces.add(new King(Color.BLACK,5,6));
        pieces.add(new Queen(Color.WHITE,7,2));
        pieces.add(new Queen(Color.BLACK,2,0));
        pieces.add(new Bishop(Color.WHITE,1,2));
        pieces.add(new Bishop(Color.BLACK,5,4));
        pieces.add(new Knight(Color.WHITE,5,1));
        pieces.add(new Knight(Color.BLACK,0,7));
        pieces.add(new Rook(Color.WHITE,2,2));
        pieces.add(new Rook(Color.BLACK,1,4));
        pieces.add(new Pawn(Color.WHITE,6,1));
        pieces.add(new Pawn(Color.BLACK,2,3));
        return pieces;
    }
}

enum Color
{
    BLACK,
    WHITE
}

abstract class Piece
{
    private Color color;
    private int x;
    private int y;
    Piece(Color color, int x, int y)
    {
        this.color = color;
        this.x = x;
        this.y = y;
    }
    Color getColor()
    {
        return color;
    }
    int getX()
    {
        return x;
    }
    int getY()
    {
        return y;
    }
}

class King extends Piece
{
    King(Color color, int x, int y)
    {
        super(color, x, y);
    }
}
class Queen extends Piece
{
    Queen(Color color, int x, int y)
    {
        super(color, x, y);
    }
}
class Bishop extends Piece
{
    Bishop(Color color, int x, int y)
    {
        super(color, x, y);
    }
}
class Knight extends Piece
{
    Knight(Color color, int x, int y)
    {
        super(color, x, y);
    }
}
class Rook extends Piece
{
    Rook(Color color, int x, int y)
    {
        super(color, x, y);
    }
}
class Pawn extends Piece
{
    Pawn(Color color, int x, int y)
    {
        super(color, x, y);
    }
}

答案 1 :(得分:0)

我猜您使用Object代表每个单独的电路板位置。因此,您可以使用映射器将对象布局(即电路板)转换为字符矩阵。

Map<Object, Character> mapper = new HashMap<Object, Character>();
mapper.put(new Queen(), 'Q');
...

在打印电路板时,您应该简单地遍历电路板方块并从上面填充的映射器中打印相应的字符。

答案 2 :(得分:0)

我认为你可以使用抽象类(或接口):

public abstract class ChessObject { 
private ChessColor color;

public abstract String getCharRepresentation();

public ChessObject(ChessColor color){
    this.color = color;
}

public ChessColor getColor() {
    return color;
}

public void setColor(ChessColor color) {
    this.color = color;
}

}

实现:

public class King extends ChessObject{

public King(ChessColor color){
    super(color);
}

@Override
public String getCharRepresentation() {
    return "K";
}

}

枚举:

public enum ChessColor {
WHITE, BLACK;
}

主要 - 示例:

public static void main(String[] args) {
    List<ChessObject> objects = new ArrayList<ChessObject>();
    objects.add(new King());
    for(ChessObject obj : objects){
        System.out.println(obj.getCharRepresentation());
    }
}