Skip to content

Commit

Permalink
Merge pull request #42 from ctabin/ascii-orientation
Browse files Browse the repository at this point in the history
Adds support for orientation handling in ASCII rendering
  • Loading branch information
ctabin authored Jul 23, 2023
2 parents b671b0a + b171353 commit e0ab55c
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 50 deletions.
64 changes: 33 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,57 +293,59 @@ UnicodePositionRenderer.render(System.out, game.getPosition());
```java
JChessGame game = JChessGame.newGame();
ASCIIPositionRenderer.render(System.out, game.getPosition());
ASCIIPositionRenderer.render(System.out, game.getPosition(), Color.WHITE);
game.play("e4", "g6", "Nf3", "Bg7", "d4", "a5", "b3");
```
The result will look like this:
```
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: ::::::::: _ :::www::: _+_ ::::_:::: ::::::::::
_ : |=|=| :: _,, :: (/) :::)#(::: )#( :::(/)::: _,, ::|=|=|:::
(_) : |#| ::"- \~:: |#| :::|#|::: |#| :::|#|::: "- \~ :::|#|::::
(_) : |#| :::|#|::: |#| :::|#|::: |#| :::|#|::: |#| :::|#|::::
: /###\ ::/###\:: /###\ ::/###\:: /###\ ::/###\:: /###\ ::/###\:::
:::::::::: ::::::::: ::::::::: ::::::::: :
__ :::::()::: () ::::()::: () ::::()::: () ::::()::: () :
/ :::::)(::: )( ::::)(::: )( ::::)(::: )( ::::)(::: )( :
/ ::::/##\:: /##\ :::/##\:: /##\ :::/##\:: /##\ :::/##\:: /##\ :
:::::::::: ::::::::: ::::::::: ::::::::: :
: ::::::::: _ :::www::: _+_ ::::::::: ::::::::::
_ : |=|=| :: _,, :: (/) :::)#(::: )#( ::::::::: _,, ::|=|=|:::
(_) : |#| ::"- \~:: |#| :::|#|::: |#| ::::::::: "- \~ :::|#|::::
(_) : |#| :::|#|::: |#| :::|#|::: |#| ::::::::: |#| :::|#|::::
: /###\ ::/###\:: /###\ ::/###\:: /###\ ::::::::: /###\ ::/###\:::
:::::::::: ::::::::: ::::::::: ::::_:::: :
__ :::::::::: () ::::()::: () ::::()::: () :::(/)::: () :
/ :::::::::: )( ::::)(::: )( ::::)(::: )( :::|#|::: )( :
/ :::::::::: /##\ :::/##\:: /##\ :::/##\:: /##\ :::|#|::: /##\ :
:::::::::: ::::::::: ::::::::: ::/###\:: :
: ::::::::: ::::::::: ::::::::: ::::::::::
: ::::::::: ::::::::: ::::::::: ::::::::::
/ : ::::::::: ::::::::: ::::::::: ::::::::::
(_) : ::::::::: ::::::::: ::::::::: ::::::::::
: ::::::::: ::::::::: ::::::::: () ::::::::::
/ : ::::::::: ::::::::: ::::::::: )( ::::::::::
(_) : ::::::::: ::::::::: ::::::::: /##\ ::::::::::
: ::::::::: ::::::::: ::::::::: ::::::::::
:::::::::: ::::::::: ::::::::: ::::::::: :
_ :::::::::: ::::::::: ::::::::: ::::::::: :
|_ :::::::::: ::::::::: ::::::::: ::::::::: :
_) :::::::::: ::::::::: ::::::::: ::::::::: :
_ :::::()::: ::::::::: ::::::::: ::::::::: :
|_ :::::)(::: ::::::::: ::::::::: ::::::::: :
_) ::::/##\:: ::::::::: ::::::::: ::::::::: :
:::::::::: ::::::::: ::::::::: ::::::::: :
: ::::::::: ::::::::: ::::::::: ::::::::::
. : ::::::::: ::::::::: ::::::::: ::::::::::
/| : ::::::::: ::::::::: ::::::::: ::::::::::
'-| : ::::::::: ::::::::: ::::::::: ::::::::::
. : ::::::::: ::::()::: () ::::::::: ::::::::::
/| : ::::::::: ::::)(::: )( ::::::::: ::::::::::
'-| : ::::::::: :::/__\:: /__\ ::::::::: ::::::::::
: ::::::::: ::::::::: ::::::::: ::::::::::
:::::::::: ::::::::: ::::::::: ::::::::: :
_ :::::::::: ::::::::: ::::::::: ::::::::: :
_) :::::::::: ::::::::: ::::::::: ::::::::: :
_) :::::::::: ::::::::: ::::::::: ::::::::: :
:::::::::: ::::::::: ::::::::: ::::::::: :
_ :::::::::: () ::::::::: ::::::::: _,, ::::::::: :
_) :::::::::: )( ::::::::: ::::::::: "- \~ ::::::::: :
_) :::::::::: /__\ ::::::::: ::::::::: | | ::::::::: :
:::::::::: ::::::::: ::::::::: /___\ ::::::::: :
: ::::::::: ::::::::: ::::::::: ::::::::::
_ : () ::::()::: () ::::()::: () ::::()::: () ::::()::::
) : )( ::::)(::: )( ::::)(::: )( ::::)(::: )( ::::)(::::
/_ : /__\ :::/__\:: /__\ :::/__\:: /__\ :::/__\:: /__\ :::/__\:::
_ : () ::::::::: () ::::::::: ::::()::: () ::::()::::
) : )( ::::::::: )( ::::::::: ::::)(::: )( ::::)(::::
/_ : /__\ ::::::::: /__\ ::::::::: :::/__\:: /__\ :::/__\:::
: ::::::::: ::::::::: ::::::::: ::::::::::
:::::::::: ::::_:::: www :::_+_::: _ ::::::::: :
:::|_|_|:: _,, :::(/)::: ) ( :::) (::: (/) :: _,, :: |_|_| :
/| ::::| |::: "- \~ :::| |::: | | :::| |::: | | ::"- \~:: | | :
| ::::| |::: | | :::| |::: | | :::| |::: | | :::| |::: | | :
:::/___\:: /___\ ::/___\:: /___\ ::/___\:: /___\ ::/___\:: /___\ :
:::|_|_|:: _,, :::(/)::: ) ( :::) (::: (/) ::::::::: |_|_| :
/| ::::| |::: "- \~ :::| |::: | | :::| |::: | | ::::::::: | | :
| ::::| |::: | | :::| |::: | | :::| |::: | | ::::::::: | | :
:::/___\:: /___\ ::/___\:: /___\ ::/___\:: /___\ ::::::::: /___\ :
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
_ _ _ __ __ _
/\ |_) / | \ |_ |_ / |_|
/--\ |_) \_ |_/ |__ | \_? | |

```

The [ASCIIPositionRenderer](src/main/java/ch/astorm/jchess/util/ASCIIPositionRenderer.java) class can
Expand Down
82 changes: 69 additions & 13 deletions src/main/java/ch/astorm/jchess/util/ASCIIPositionRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Simple utility class to render a {@code Position}.
*/
public class ASCIIPositionRenderer extends AbstractTextPositionRenderer {
private static final String[] ROW_HEADER = new String[]
private static final String[] ROW_HEADER_WHITE = new String[]
{
" ",
" _ ",
Expand Down Expand Up @@ -54,17 +54,63 @@ public class ASCIIPositionRenderer extends AbstractTextPositionRenderer {
" ",
" /| ",
" | ",
" "
};

private static final String[] ROW_HEADER_BLACK = new String[]
{
" ",
" ",
" /| ",
" | ",
" ",
" ",
" _ ",
" ) ",
" /_ ",
" ",
" ",
" _ ",
" _) ",
" _) ",
" ",
" ",
" . ",
" /| ",
" '-| ",
" ",
" ",
" _ ",
" |_ ",
" _) ",
" ",
" ",
" ",
" / ",
" (_) ",
" ",
" ",
" __ ",
" / ",
" / ",
" ",
" ",
" _ ",
" (_) ",
" (_) ",
" "
};

private final ASCIIStyle style;
private Color orientation;

/**
* Creates a renderer to the specified {@code out} stream.
*/
public ASCIIPositionRenderer(PrintStream out, ASCIIStyle style) {
public ASCIIPositionRenderer(PrintStream out, ASCIIStyle style, Color orientation) {
super(out);
this.style = style;
this.orientation = orientation;
}

/**
Expand All @@ -77,14 +123,15 @@ public ASCIIStyle getStyle() {
/**
* Renders the given {@code position} with a {@link DefaultASCIIStyle}.
*/
public static void render(PrintStream out, Position position) {
new ASCIIPositionRenderer(out, new DefaultASCIIStyle()).render(position);
public static void render(PrintStream out, Position position, Color orientation) {
new ASCIIPositionRenderer(out, new DefaultASCIIStyle(), orientation).render(position);
}

@Override
public CharSequence renderToString(Position position) {
Board board = position.getBoard();

boolean isWhiteOrientation = orientation==Color.WHITE;

char whiteBackgroundStyle = style.getWhiteBackgroundStyle();
char blackBackgroundStyle = style.getBlackBackgroundStyle();
char borderStyle = style.getBorderStyle();
Expand All @@ -110,8 +157,11 @@ public CharSequence renderToString(Position position) {
Moveable moveable = position.get(coordinate);
if(moveable!=null) { style.renderCell(cell, coordinate, moveable); }

int rowOffset = (nbRows - row - 1)*ASCIIStyle.NB_ROWS_PER_CELL;
int colOffset = col*ASCIIStyle.NB_COLUMNS_PER_CELL;
int targetRow = isWhiteOrientation ? row : nbRows - row -1;
int targetCol = isWhiteOrientation ? col : nbColumns - col -1;

int rowOffset = (nbRows - targetRow - 1)*ASCIIStyle.NB_ROWS_PER_CELL;
int colOffset = targetCol*ASCIIStyle.NB_COLUMNS_PER_CELL;
for(int ti=0 ; ti<ASCIIStyle.NB_ROWS_PER_CELL ; ++ti) {
for(int tc=0 ; tc<ASCIIStyle.NB_COLUMNS_PER_CELL ; ++tc) {
asciiBoard[rowOffset+ti][colOffset+tc] = cell[ti][tc];
Expand All @@ -130,7 +180,7 @@ public CharSequence renderToString(Position position) {

//whole board
for(int r=0 ; r<nbTotalRows ; ++r) {
String headerRow = ROW_HEADER[r];
String headerRow = isWhiteOrientation ? ROW_HEADER_WHITE[r] : ROW_HEADER_BLACK[r];
for(int hr=0 ; hr<headerRow.length() ; ++hr) { builder.append(headerRow.charAt(hr)); }

builder.append(borderStyle);
Expand All @@ -147,11 +197,17 @@ public CharSequence renderToString(Position position) {
printRow(builder, nbTotalColumns+2, i -> borderStyle);
builder.append(lineSeparator);

builder.append(" _ _ _ __ __ _ ").append(lineSeparator);
builder.append(" /\\ |_) / | \\ |_ |_ / |_| ").append(lineSeparator);
builder.append(" /--\\ |_) \\_ |_/ |__ | \\_? | | ").append(lineSeparator);
builder.append(" ").append(lineSeparator);

if(isWhiteOrientation) {
builder.append(" _ _ _ __ __ _ ").append(lineSeparator);
builder.append(" /\\ |_) / | \\ |_ |_ / |_| ").append(lineSeparator);
builder.append(" /--\\ |_) \\_ |_/ |__ | \\_? | | ").append(lineSeparator);
builder.append(" ").append(lineSeparator);
} else {
builder.append(" _ __ __ _ _ _ ").append(lineSeparator);
builder.append(" |_| / |_ |_ | \\ / |_) /\\ ").append(lineSeparator);
builder.append(" | | \\_? | |__ |_/ \\_ |_) /--\\ ").append(lineSeparator);
builder.append(" ").append(lineSeparator);
}
return builder;
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/java/ch/astorm/jchess/io/PGNReadWriteTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import ch.astorm.jchess.JChessGame;
import ch.astorm.jchess.JChessGame.Status;
import ch.astorm.jchess.core.Color;
import ch.astorm.jchess.io.PGNReader.PGNReaderException;
import ch.astorm.jchess.util.ASCIIPositionRenderer;
import java.io.IOException;
Expand Down Expand Up @@ -58,7 +59,7 @@ private void testPGN(String resource) throws IOException {
pe.getGame().getMetadata().forEach((k,v) -> System.out.println("- "+k+": "+v));
System.err.println("------------------------------------------");
System.err.println("Position before the move:\n");
ASCIIPositionRenderer.render(System.err, pe.getGame().getPosition());
ASCIIPositionRenderer.render(System.err, pe.getGame().getPosition(), Color.WHITE);
System.err.println("==========================================");
fail("Unable to parse PGN game", pe);
}
Expand Down
31 changes: 26 additions & 5 deletions src/test/java/ch/astorm/jchess/util/ASCIIPositionRendererTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,48 @@
package ch.astorm.jchess.util;

import ch.astorm.jchess.JChessGame;
import ch.astorm.jchess.core.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class ASCIIPositionRendererTest {
@Test
public void testRenderingDefault() throws URISyntaxException, IOException {
public void testRenderingDefaultWhite() throws URISyntaxException, IOException {
JChessGame game = JChessGame.newGame();

game.play("e4", "g6", "Nf3", "Bg7", "d4", "a5", "b3");

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(PrintStream stream = new PrintStream(baos, true, StandardCharsets.US_ASCII)) { ASCIIPositionRenderer.render(stream, game.getPosition()); }
try(PrintStream stream = new PrintStream(baos, true, StandardCharsets.US_ASCII)) { ASCIIPositionRenderer.render(stream, game.getPosition(), Color.WHITE); }
String str = baos.toString(StandardCharsets.US_ASCII);

String expected;
try(InputStream is = ASCIIPositionRendererTest.class.getResourceAsStream("ASCIIPositionTestWhite.txt")) {
expected = IOUtils.toString(is, StandardCharsets.US_ASCII).replace("\n", System.lineSeparator());
}

assertEquals(expected, str);
}

@Test
public void testRenderingDefaultBlack() throws URISyntaxException, IOException {
JChessGame game = JChessGame.newGame();
game.play("e4", "g6", "Nf3", "Bg7", "d4", "a5", "b3");

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(PrintStream stream = new PrintStream(baos, true, StandardCharsets.US_ASCII)) { ASCIIPositionRenderer.render(stream, game.getPosition(), Color.BLACK); }
String str = baos.toString(StandardCharsets.US_ASCII);

String expected;
try(InputStream is = ASCIIPositionRendererTest.class.getResourceAsStream("ASCIIPositionTemplate.txt")) {
try(InputStream is = ASCIIPositionRendererTest.class.getResourceAsStream("ASCIIPositionTestBlack.txt")) {
expected = IOUtils.toString(is, StandardCharsets.US_ASCII).replace("\n", System.lineSeparator());
}

Expand All @@ -36,7 +57,7 @@ public void testRenderingCustomSeparator() throws URISyntaxException, IOExceptio
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(PrintStream stream = new PrintStream(baos, true, StandardCharsets.US_ASCII)) {
ASCIIStyle style = new DefaultASCIIStyle();
ASCIIPositionRenderer renderer = new ASCIIPositionRenderer(stream, style);
ASCIIPositionRenderer renderer = new ASCIIPositionRenderer(stream, style, Color.WHITE);
assertEquals(System.lineSeparator(), renderer.getLineSeparator());
assertEquals(style, renderer.getStyle());
renderer.setLineSeparator("\n");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: ::::::::: _ :::_+_::: www ::::_:::: ::::::::::
: |_|_| ::::::::: (/) :::) (::: ) ( :::(/)::: _,, ::|_|_|:::
/| : | | ::::::::: | | :::| |::: | | :::| |::: "- \~ :::| |::::
| : | | ::::::::: | | :::| |::: | | :::| |::: | | :::| |::::
: /___\ ::::::::: /___\ ::/___\:: /___\ ::/___\:: /___\ ::/___\:::
:::::::::: ::::::::: ::::::::: ::::::::: :
_ :::::()::: () ::::()::: ::::::::: () ::::::::: () :
) :::::)(::: )( ::::)(::: ::::::::: )( ::::::::: )( :
/_ ::::/__\:: /__\ :::/__\:: ::::::::: /__\ ::::::::: /__\ :
:::::::::: ::::::::: ::::::::: ::::::::: :
: ::::::::: ::::::::: ::::::::: ::::::::::
_ : ::::::::: _,, ::::::::: ::::::::: () ::::::::::
_) : ::::::::: "- \~ ::::::::: ::::::::: )( ::::::::::
_) : ::::::::: | | ::::::::: ::::::::: /__\ ::::::::::
: ::::::::: /___\ ::::::::: ::::::::: ::::::::::
:::::::::: ::::::::: ::::::::: ::::::::: :
. :::::::::: ::::::::: () ::::()::: ::::::::: :
/| :::::::::: ::::::::: )( ::::)(::: ::::::::: :
'-| :::::::::: ::::::::: /__\ :::/__\:: ::::::::: :
:::::::::: ::::::::: ::::::::: ::::::::: :
: ::::::::: ::::::::: ::::::::: ::::::::::
_ : ::::::::: ::::::::: ::::::::: ::::()::::
|_ : ::::::::: ::::::::: ::::::::: ::::)(::::
_) : ::::::::: ::::::::: ::::::::: :::/##\:::
: ::::::::: ::::::::: ::::::::: ::::::::::
:::::::::: ::::::::: ::::::::: ::::::::: :
:::::::::: () ::::::::: ::::::::: ::::::::: :
/ :::::::::: )( ::::::::: ::::::::: ::::::::: :
(_) :::::::::: /##\ ::::::::: ::::::::: ::::::::: :
:::::::::: ::::::::: ::::::::: ::::::::: :
: ::::_:::: ::::::::: ::::::::: ::::::::::
__ : () :::(/)::: () ::::()::: () ::::()::: () ::::::::::
/ : )( :::|#|::: )( ::::)(::: )( ::::)(::: )( ::::::::::
/ : /##\ :::|#|::: /##\ :::/##\:: /##\ :::/##\:: /##\ ::::::::::
: ::/###\:: ::::::::: ::::::::: ::::::::::
:::::::::: ::::::::: _+_ :::www::: _ ::::::::: :
_ :::|=|=|:: _,, ::::::::: )#( :::)#(::: (/) :: _,, :: |=|=| :
(_) ::::|#|::: "- \~ ::::::::: |#| :::|#|::: |#| ::"- \~:: |#| :
(_) ::::|#|::: |#| ::::::::: |#| :::|#|::: |#| :::|#|::: |#| :
:::/###\:: /###\ ::::::::: /###\ ::/###\:: /###\ ::/###\:: /###\ :
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
_ __ __ _ _ _
|_| / |_ |_ | \ / |_) /\
| | \_? | |__ |_/ \_ |_) /--\


Loading

0 comments on commit e0ab55c

Please sign in to comment.