chess: pawn promotion
For a lack of a better idea, bind board and piece rotation to X/Y chess::do_move no longer advances the turn--prior to this change, castle moves incorrectly double-negated turn.
This commit is contained in:
parent
ebb1955500
commit
bf9a862a43
Binary file not shown.
@ -82,6 +82,9 @@ move_t * moves_pawn(game_state& game_state, int8_t origin, move_t * moves)
|
||||
if (other.type == 0) {
|
||||
int8_t to_position = xy_to_position(x, y);
|
||||
if (!speculative_check(game_state, origin, to_position, self.type)) {
|
||||
if (y == 0 || y == 7) {
|
||||
type = move_type::pawn_promote;
|
||||
}
|
||||
*moves++ = {type, to_position};
|
||||
}
|
||||
} else {
|
||||
@ -289,6 +292,8 @@ void game_init(game_state& game_state)
|
||||
game_state.interaction.selected_position = -1;
|
||||
game_state.interaction.last_move.from_position = -1;
|
||||
game_state.interaction.last_move.to_position = -1;
|
||||
game_state.interaction.promotion_ix[0] = 0;
|
||||
game_state.interaction.promotion_ix[1] = 0;
|
||||
board_init(game_state);
|
||||
}
|
||||
|
||||
@ -406,6 +411,15 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move)
|
||||
piece_list_delete(game_state.piece_list, en_passant_piece.piece_list_offset);
|
||||
}
|
||||
break;
|
||||
case move_type::pawn_promote:
|
||||
{
|
||||
serial::string("move pawn promote\n");
|
||||
if (origin.type > 0)
|
||||
origin.type = promotion_types[game_state.interaction.promotion_ix[0]];
|
||||
else
|
||||
origin.type = -promotion_types[game_state.interaction.promotion_ix[1]];
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -416,8 +430,6 @@ void do_move(game_state& game_state, int8_t from_position, move_t& move)
|
||||
game_state.piece_list.piece[origin.piece_list_offset] = &destination;
|
||||
game_state.interaction.last_move.from_position = from_position;
|
||||
game_state.interaction.last_move.to_position = move.to_position;
|
||||
|
||||
game_state.turn = -game_state.turn;
|
||||
}
|
||||
|
||||
void select_position(game_state& game_state, int8_t x, int8_t y)
|
||||
@ -439,6 +451,7 @@ void select_position(game_state& game_state, int8_t x, int8_t y)
|
||||
do_move(game_state,
|
||||
game_state.interaction.selected_position, // from
|
||||
game_state.interaction.moves.moves[moves_ix]); // to
|
||||
game_state.turn = -game_state.turn;
|
||||
// fall through to deselect
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,13 @@ constexpr int8_t queen = 5;
|
||||
constexpr int8_t king = 6;
|
||||
};
|
||||
|
||||
constexpr int8_t promotion_types[4] = {
|
||||
piece_type::knight,
|
||||
piece_type::bishop,
|
||||
piece_type::rook,
|
||||
piece_type::queen,
|
||||
};
|
||||
|
||||
namespace movement_state {
|
||||
constexpr int8_t not_moved = 0;
|
||||
constexpr int8_t moved = 1;
|
||||
@ -45,6 +52,7 @@ enum struct move_type : int8_t {
|
||||
castle_long,
|
||||
pawn_double_advance,
|
||||
pawn_en_passant_capture,
|
||||
pawn_promote,
|
||||
};
|
||||
|
||||
struct move_t {
|
||||
@ -81,6 +89,7 @@ struct interaction_state {
|
||||
int8_t selected_position;
|
||||
struct moves_list moves;
|
||||
struct annotation_list annotation_list;
|
||||
int8_t promotion_ix[2];
|
||||
};
|
||||
|
||||
struct game_state {
|
||||
|
@ -46,6 +46,8 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
||||
cursor.y += static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * -0.0015 * invert;
|
||||
cursor.button[frame_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0;
|
||||
cursor.button[frame_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0;
|
||||
cursor.button[frame_ix].x = ft0::data_transfer::digital_button::x(data.digital_button) == 0;
|
||||
cursor.button[frame_ix].y = ft0::data_transfer::digital_button::y(data.digital_button) == 0;
|
||||
bool start = ft0::data_transfer::digital_button::start(data.digital_button) == 0;
|
||||
if (start) {
|
||||
cursor.x = 3.5f;
|
||||
@ -70,27 +72,56 @@ void cursor_update(struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor.x < -1.0f) cursor.x = -1.0f;
|
||||
if (cursor.x > 8.0f) cursor.x = 8.0f;
|
||||
if (cursor.x < -2.0f) cursor.x = -2.0f;
|
||||
if (cursor.x > 9.0f) cursor.x = 9.0f;
|
||||
if (cursor.y < -0.5f) cursor.y = -0.5f;
|
||||
if (cursor.y > 7.5f) cursor.y = 7.5f;
|
||||
}
|
||||
}
|
||||
|
||||
static bool piece_rotation = false;
|
||||
static bool board_rotation = false;
|
||||
|
||||
void promotion_select(chess::game_state& game_state,
|
||||
int side,
|
||||
int promotion_ix)
|
||||
{
|
||||
if (promotion_ix < 0 || promotion_ix >= 4) {
|
||||
return;
|
||||
}
|
||||
game_state.interaction.promotion_ix[side] = promotion_ix;
|
||||
}
|
||||
|
||||
void cursor_events(chess::game_state& game_state, struct render::cursor_state& cursor_state, uint32_t frame_ix)
|
||||
{
|
||||
for (int cursor_ix = 0; cursor_ix < render::cursor_state::num_cursors; cursor_ix++) {
|
||||
auto& cursor = cursor_state.cur[cursor_ix];
|
||||
const uint32_t last_frame = (frame_ix + 1) & 1;
|
||||
const int8_t x = cursor.x + 0.5f;
|
||||
const float x = cursor.x + 0.5f;
|
||||
const int8_t y = cursor.y + 0.5f;
|
||||
if (cursor.button[last_frame].a != cursor.button[frame_ix].a && cursor.button[frame_ix].a) {
|
||||
chess::clear_annotations(game_state);
|
||||
chess::select_position(game_state, x, y);
|
||||
if (x > 8.5) {
|
||||
serial::string("white side\n");
|
||||
int8_t promotion_ix = y;
|
||||
promotion_select(game_state, 0, promotion_ix);
|
||||
} else if (x < -0.5) {
|
||||
serial::string("black side\n");
|
||||
int8_t promotion_ix = 7 - y;
|
||||
promotion_select(game_state, 1, promotion_ix);
|
||||
} else {
|
||||
chess::select_position(game_state, x, y);
|
||||
}
|
||||
}
|
||||
if (cursor.button[last_frame].b != cursor.button[frame_ix].b && cursor.button[frame_ix].b) {
|
||||
chess::annotate_position(game_state, x, y);
|
||||
}
|
||||
if (cursor.button[last_frame].x != cursor.button[frame_ix].x && cursor.button[frame_ix].x) {
|
||||
piece_rotation = !piece_rotation;
|
||||
}
|
||||
if (cursor.button[last_frame].y != cursor.button[frame_ix].y && cursor.button[frame_ix].y) {
|
||||
board_rotation = !board_rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,27 +165,31 @@ void main()
|
||||
vt.board_rotation = 0.f;
|
||||
|
||||
auto piece_rotation_animator = render::animator<float>(0.f);
|
||||
auto board_rotation_animator = render::animator<float>(0.f);
|
||||
|
||||
struct render::cursor_state cursor_state = render::cursor_state();
|
||||
|
||||
constexpr float pi = 3.141592653589793f;
|
||||
piece_rotation = false;
|
||||
board_rotation = false;
|
||||
|
||||
while (true) {
|
||||
input::state_update(send_buf, recv_buf);
|
||||
cursor_update(cursor_state, frame_ix);
|
||||
cursor_events(game_state, cursor_state, frame_ix);
|
||||
|
||||
float target = game_state.turn == 1 ? 0.f : pi;
|
||||
piece_rotation_animator.set_target(target, 60);
|
||||
//vt.board_rotation = piece_rotation_animator.interpolate();
|
||||
//vt.piece_rotation = piece_rotation_animator.interpolate();
|
||||
//float target = game_state.turn == 1 ? 0.f : pi;
|
||||
piece_rotation_animator.set_target(piece_rotation ? pi : 0.f, 60);
|
||||
board_rotation_animator.set_target(board_rotation ? pi : 0.f, 60);
|
||||
vt.board_rotation = board_rotation_animator.interpolate();
|
||||
vt.piece_rotation = piece_rotation_animator.interpolate();
|
||||
|
||||
ta_polygon_converter_init(opb_size.total(),
|
||||
ta_alloc,
|
||||
640 / 32,
|
||||
480 / 32);
|
||||
|
||||
render::render(game_state, vt, cursor_state);
|
||||
render::render(vt, game_state, cursor_state);
|
||||
|
||||
*reinterpret_cast<ta_global_parameter::end_of_list *>(store_queue) =
|
||||
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
||||
|
@ -190,7 +190,7 @@ void draw_moves(const view_transform vt,
|
||||
}
|
||||
|
||||
void draw_piece(const view_transform vt,
|
||||
int8_t type, int8_t x, int8_t y)
|
||||
int8_t type, float x, float y)
|
||||
{
|
||||
bool white = type > 0;
|
||||
uint32_t color = white ? 0xffdddddd : 0xff444444;
|
||||
@ -337,8 +337,50 @@ void draw_interaction(const view_transform vt,
|
||||
render::draw_illumination(vt, interaction.last_move.to_position, yellow_highlight);
|
||||
}
|
||||
|
||||
void render(const chess::game_state& game_state,
|
||||
const view_transform vt,
|
||||
void draw_promotion_selection(const view_transform vt,
|
||||
const chess::game_state& game_state)
|
||||
{
|
||||
constexpr uint32_t yellow_highlight = 0x7fffff33;
|
||||
|
||||
draw_model(vt,
|
||||
square::vertices,
|
||||
square::faces,
|
||||
square::num_faces,
|
||||
yellow_highlight,
|
||||
8.5f, game_state.interaction.promotion_ix[0],
|
||||
illumination_z,
|
||||
1.0f, // scale
|
||||
0.0f, // rotation
|
||||
true, // always
|
||||
true); // alpha
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
draw_piece(vt,
|
||||
chess::promotion_types[i],
|
||||
8.5f, i);
|
||||
}
|
||||
|
||||
draw_model(vt,
|
||||
square::vertices,
|
||||
square::faces,
|
||||
square::num_faces,
|
||||
yellow_highlight,
|
||||
-1.5f, 7 - game_state.interaction.promotion_ix[1],
|
||||
illumination_z,
|
||||
1.0f, // scale
|
||||
0.0f, // rotation
|
||||
true, // always
|
||||
true); // alpha
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
draw_piece(vt,
|
||||
-chess::promotion_types[i],
|
||||
-1.5f, 7 - i);
|
||||
}
|
||||
}
|
||||
|
||||
void render(const view_transform vt,
|
||||
const chess::game_state& game_state,
|
||||
const cursor_state cursor_state)
|
||||
{
|
||||
render::draw_board(vt);
|
||||
@ -347,6 +389,8 @@ void render(const chess::game_state& game_state,
|
||||
render::draw_annotation(vt, game_state.interaction.annotation_list);
|
||||
|
||||
render::draw_pieces(vt, game_state);
|
||||
render::draw_promotion_selection(vt, game_state);
|
||||
|
||||
render::draw_moves(vt, game_state.interaction.moves);
|
||||
for (int i = 0; i < cursor_state::num_cursors; i++) {
|
||||
auto& cursor = cursor_state.cur[i];
|
||||
|
@ -46,6 +46,8 @@ struct animator {
|
||||
struct button {
|
||||
bool a;
|
||||
bool b;
|
||||
bool x;
|
||||
bool y;
|
||||
};
|
||||
|
||||
struct cursor {
|
||||
@ -78,8 +80,8 @@ struct cursor_state {
|
||||
}
|
||||
};
|
||||
|
||||
void render(const chess::game_state& game_state,
|
||||
const view_transform vt,
|
||||
void render(const view_transform vt,
|
||||
const chess::game_state& game_state,
|
||||
const cursor_state cursor_state);
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user