Chess_Constants:
module Chess
#--------------------------------------------------------------------------
# * Color
#--------------------------------------------------------------------------
WHITE = true
BLACK = false
#--------------------------------------------------------------------------
# * Pieces
#--------------------------------------------------------------------------
W_PAWN = 0
W_ROOK = 1
W_KNIGHT = 2
W_BISHOP = 3
W_QUEEN = 4
W_KING = 5
B_PAWN = 6
B_ROOK = 7
B_KNIGHT = 8
B_BISHOP = 9
B_QUEEN = 10
B_KING = 11
NO_PIECE = 12
OFF_BOARD = -2;
#--------------------------------------------------------------------------
# * Squares
#--------------------------------------------------------------------------
A8 = 21; B8 = 22; C8 = 23; D8 = 24; E8 = 25; F8 = 26; G8 = 27; H8 = 28;
A7 = 31; B7 = 32; C7 = 33; D7 = 34; E7 = 35; F7 = 36; G7 = 37; H7 = 38;
A6 = 41; B6 = 42; C6 = 43; D6 = 44; E6 = 45; F6 = 46; G6 = 47; H6 = 48;
A5 = 51; B5 = 52; C5 = 53; D5 = 54; E5 = 55; F5 = 56; G5 = 57; H5 = 58;
A4 = 61; B4 = 62; C4 = 63; D4 = 64; E4 = 65; F4 = 66; G4 = 67; H4 = 68;
A3 = 71; B3 = 72; C3 = 73; D3 = 74; E3 = 75; F3 = 76; G3 = 77; H3 = 78;
A2 = 81; B2 = 82; C2 = 83; D2 = 84; E2 = 85; F2 = 86; G2 = 87; H2 = 88;
A1 = 91; B1 = 92; C1 = 93; D1 = 94; E1 = 95; F1 = 96; G1 = 97; H1 = 98;
NO_SQUARE = -1;
#--------------------------------------------------------------------------
# * Ranks
#--------------------------------------------------------------------------
RANK_1 = 8; RANK_2 = 7; RANK_3 = 6; RANK_4 = 5;
RANK_5 = 4; RANK_6 = 3; RANK_7 = 2; RANK_8 = 1;
#--------------------------------------------------------------------------
# * Files
#--------------------------------------------------------------------------
FILE_A = 1; FILE_B = 2; FILE_C = 3; FILE_D = 4;
FILE_E = 5; FILE_F = 6; FILE_G = 7; FILE_H = 8;
#--------------------------------------------------------------------------
# * Strings
#--------------------------------------------------------------------------
SFILES = []
SFILES[FILE_A] = "a"; SFILES[FILE_B] = "b"; SFILES[FILE_C] = "c";
SFILES[FILE_D] = "d"; SFILES[FILE_E] = "e"; SFILES[FILE_F] = "f";
SFILES[FILE_G] = "g"; SFILES[FILE_H] = "h";
#--------------------------------------------------------------------------
# * Values
#--------------------------------------------------------------------------
PVALUE = []
PVALUE[NO_PIECE] = 0
PVALUE[W_PAWN] = 100
PVALUE[W_KNIGHT] = 300
PVALUE[W_BISHOP] = 300
PVALUE[W_ROOK] = 600
PVALUE[W_QUEEN] = 900
PVALUE[W_KING] = 0
PVALUE[B_PAWN] = -100
PVALUE[B_KNIGHT] = -300
PVALUE[B_BISHOP] = -300
PVALUE[B_ROOK] = -600
PVALUE[B_QUEEN] = -900
PVALUE[B_KING] = 0
DRAW = 0
CHECKMATE = 1000
INFINITY = CHECKMATE + 1
end
Chess_MoveGeneration:
class Chess_MoveGeneration
#--------------------------------------------------------------------------
# * Move exists?
#--------------------------------------------------------------------------
def move_exists(pos, move)
legalMoves = []
legalMoves += generateCapture(pos)
legalMoves += generateQuiet(pos)
legalMoves.each_index do |i|
if(legalMoves[i][0] == move[0] && legalMoves[i][1] == move[1])
return true
end
end
return false
end
#--------------------------------------------------------------------------
# * Generate quiet moves
#--------------------------------------------------------------------------
def generateQuiet(pos)
moves = []
i = -1
while(i < 120)
i += 1
p = pos.board[i]
next if(p == nil || p == Chess::OFF_BOARD || p == Chess::NO_PIECE)
color = (p <= Chess::W_KING) ? Chess::WHITE : Chess::BLACK
next if(color != pos.side_to_move)
is_rook = (p == Chess::W_ROOK || p == Chess::B_ROOK)
is_knight = (p == Chess::W_KNIGHT || p == Chess::B_KNIGHT)
is_bishop = (p == Chess::W_BISHOP || p == Chess::B_BISHOP)
is_queen = (p == Chess::W_QUEEN || p == Chess::B_QUEEN)
is_king = (p == Chess::W_KING || p == Chess::B_KING)
#
# Pawns
#
if(p == Chess::W_PAWN)
if(pos.board[i - 10] == Chess::NO_PIECE)
moves.push([i, i - 10])
if(i >= Chess::A2 && pos.board[i - 20] == Chess::NO_PIECE)
moves.push([i, i - 20])
end
end
end
if(p == Chess::B_PAWN)
if(pos.board[i + 10] == Chess::NO_PIECE)
moves.push([i, i + 10])
if(i <= Chess::H7 && pos.board[i + 20] == Chess::NO_PIECE)
moves.push([i, i + 20])
end
end
end
#
# Knight movement
#
if(is_knight)
moves.push([i, i+21]) if(pos.board[i+21] == Chess::NO_PIECE)
moves.push([i, i+19]) if(pos.board[i+19] == Chess::NO_PIECE)
moves.push([i, i+12]) if(pos.board[i+12] == Chess::NO_PIECE)
moves.push([i, i+8]) if(pos.board[i+8] == Chess::NO_PIECE)
moves.push([i, i-21]) if(pos.board[i-21] == Chess::NO_PIECE)
moves.push([i, i-19]) if(pos.board[i-19] == Chess::NO_PIECE)
moves.push([i, i-12]) if(pos.board[i-12] == Chess::NO_PIECE)
moves.push([i, i-8]) if(pos.board[i-8] == Chess::NO_PIECE)
end
#
# Linear movement
#
if(is_rook || is_queen)
j = 1
while(pos.board[i + j] == Chess::NO_PIECE)
moves.push([i, i+j])
j += 1
end
j = 1
while(pos.board[i - j] == Chess::NO_PIECE)
moves.push([i, i-j])
j += 1
end
j = 1
while(pos.board[i + j*10] == Chess::NO_PIECE)
moves.push([i, i+j*10])
j += 1
end
j = 1
while(pos.board[i - j*10] == Chess::NO_PIECE)
moves.push([i, i-j*10])
j += 1
end
end
#
# Diagonal movement
#
if(is_bishop || is_queen)
j = 1
while(pos.board[i + j*10 + j] == Chess::NO_PIECE)
moves.push([i, i+j*10 + j])
j += 1
end
j = 1
while(pos.board[i - j*10 + j] == Chess::NO_PIECE)
moves.push([i, i-j*10 + j])
j += 1
end
j = 1
while(pos.board[i + j*10 - j] == Chess::NO_PIECE)
moves.push([i, i+j*10 - j])
j += 1
end
j = 1
while(pos.board[i - j*10 - j] == Chess::NO_PIECE)
moves.push([i, i-j*10 - j])
j += 1
end
end
#
# King movement
#
if(is_king)
moves.push([i, i+1]) if(pos.board[i+1] == Chess::NO_PIECE)
moves.push([i, i-1]) if(pos.board[i-1] == Chess::NO_PIECE)
moves.push([i, i+10]) if(pos.board[i+10] == Chess::NO_PIECE)
moves.push([i, i-10]) if(pos.board[i-10] == Chess::NO_PIECE)
moves.push([i, i+11]) if(pos.board[i+11] == Chess::NO_PIECE)
moves.push([i, i-11]) if(pos.board[i-11] == Chess::NO_PIECE)
moves.push([i, i+9]) if(pos.board[i+9] == Chess::NO_PIECE)
moves.push([i, i-9]) if(pos.board[i-9] == Chess::NO_PIECE)
end
end
return moves
end
#--------------------------------------------------------------------------
# * Generate capture moves
#--------------------------------------------------------------------------
def generateCapture(pos)
moves = []
i = -1
while(i < 120)
i += 1
p = pos.board[i]
next if(p == nil || p == Chess::OFF_BOARD || p == Chess::NO_PIECE)
color = (p <= Chess::W_KING) ? Chess::WHITE : Chess::BLACK
next if(color != pos.side_to_move)
#
# Pawns
#
if(p == Chess::W_PAWN)
moves.push([i, i - 11]) if pos.is_black(pos.board[i - 11])
moves.push([i, i - 9]) if pos.is_black(pos.board[i - 9])
end
if(p == Chess::B_PAWN)
moves.push([i, i + 11]) if pos.is_white(pos.board[i + 11])
moves.push([i, i + 9]) if pos.is_white(pos.board[i + 9])
end
#
# Knight movement
#
if(p == Chess::W_KNIGHT)
moves.push([i, i+21]) if pos.is_black(pos.board[i+21])
moves.push([i, i+19]) if pos.is_black(pos.board[i+19])
moves.push([i, i+12]) if pos.is_black(pos.board[i+12])
moves.push([i, i+8]) if pos.is_black(pos.board[i+8])
moves.push([i, i-21]) if pos.is_black(pos.board[i-21])
moves.push([i, i-19]) if pos.is_black(pos.board[i-19])
moves.push([i, i-12]) if pos.is_black(pos.board[i-12])
moves.push([i, i-8]) if pos.is_black(pos.board[i-8])
end
if(p == Chess::B_KNIGHT)
moves.push([i, i+21]) if pos.is_white(pos.board[i+21])
moves.push([i, i+19]) if pos.is_white(pos.board[i+19])
moves.push([i, i+12]) if pos.is_white(pos.board[i+12])
moves.push([i, i+8]) if pos.is_white(pos.board[i+8])
moves.push([i, i-21]) if pos.is_white(pos.board[i-21])
moves.push([i, i-19]) if pos.is_white(pos.board[i-19])
moves.push([i, i-12]) if pos.is_white(pos.board[i-12])
moves.push([i, i-8]) if pos.is_white(pos.board[i-8])
end
#
# Linear movement
#
if(p == Chess::W_ROOK || p == Chess::W_QUEEN)
j = 1
j += 1 while(pos.board[i + j] == Chess::NO_PIECE)
moves.push([i, i+j]) if pos.is_black(pos.board[i + j])
j = 1
j += 1 while(pos.board[i - j] == Chess::NO_PIECE)
moves.push([i, i-j]) if pos.is_black(pos.board[i - j])
j = 1
j += 1 while(pos.board[i + j*10] == Chess::NO_PIECE)
moves.push([i, i+j*10]) if pos.is_black(pos.board[i + j*10])
j = 1
j += 1 while(pos.board[i - j*10] == Chess::NO_PIECE)
moves.push([i, i-j*10]) if pos.is_black(pos.board[i - j*10])
end
if(p == Chess::B_ROOK || p == Chess::B_QUEEN)
j = 1
j += 1 while(pos.board[i + j] == Chess::NO_PIECE)
moves.push([i, i+j]) if pos.is_white(pos.board[i + j])
j = 1
j += 1 while(pos.board[i - j] == Chess::NO_PIECE)
moves.push([i, i-j]) if pos.is_white(pos.board[i - j])
j = 1
j += 1 while(pos.board[i + j*10] == Chess::NO_PIECE)
moves.push([i, i+j*10]) if pos.is_white(pos.board[i + j*10])
j = 1
j += 1 while(pos.board[i - j*10] == Chess::NO_PIECE)
moves.push([i, i-j*10]) if pos.is_white(pos.board[i - j*10])
end
#
# Diagonal movement
#
if(p == Chess::W_BISHOP || p == Chess::W_QUEEN)
j = 1
j += 1 while(pos.board[i + j*10 + j] == Chess::NO_PIECE)
moves.push([i, i+j*10+j]) if pos.is_black(pos.board[i + j*10+j])
j = 1
j += 1 while(pos.board[i - j*10+j] == Chess::NO_PIECE)
moves.push([i, i-j*10+j]) if pos.is_black(pos.board[i - j*10+j])
j = 1
j += 1 while(pos.board[i + j*10-j] == Chess::NO_PIECE)
moves.push([i, i+j*10-j]) if pos.is_black(pos.board[i + j*10-j])
j = 1
j += 1 while(pos.board[i - j*10-j] == Chess::NO_PIECE)
moves.push([i, i-j*10-j]) if pos.is_black(pos.board[i - j*10-j])
end
if(p == Chess::B_BISHOP || p == Chess::B_QUEEN)
j = 1
j += 1 while(pos.board[i + j*10 + j] == Chess::NO_PIECE)
moves.push([i, i+j*10+j]) if pos.is_white(pos.board[i + j*10+j])
j = 1
j += 1 while(pos.board[i - j*10+j] == Chess::NO_PIECE)
moves.push([i, i-j*10+j]) if pos.is_white(pos.board[i - j*10+j])
j = 1
j += 1 while(pos.board[i + j*10-j] == Chess::NO_PIECE)
moves.push([i, i+j*10-j]) if pos.is_white(pos.board[i + j*10-j])
j = 1
j += 1 while(pos.board[i - j*10-j] == Chess::NO_PIECE)
moves.push([i, i-j*10-j]) if pos.is_white(pos.board[i - j*10-j])
end
#
# King movement
#
if(p == Chess::W_KING)
moves.push([i, i+1]) if pos.is_black(pos.board[i+1])
moves.push([i, i-1]) if pos.is_black(pos.board[i-1])
moves.push([i, i+10]) if pos.is_black(pos.board[i+10])
moves.push([i, i-10]) if pos.is_black(pos.board[i-10])
moves.push([i, i+11]) if pos.is_black(pos.board[i+11])
moves.push([i, i-11]) if pos.is_black(pos.board[i-11])
moves.push([i, i+9]) if pos.is_black(pos.board[i+9])
moves.push([i, i-9]) if pos.is_black(pos.board[i-9])
end
if(p == Chess::B_KING)
moves.push([i, i+1]) if pos.is_white(pos.board[i+1])
moves.push([i, i-1]) if pos.is_white(pos.board[i-1])
moves.push([i, i+10]) if pos.is_white(pos.board[i+10])
moves.push([i, i-10]) if pos.is_white(pos.board[i-10])
moves.push([i, i+11]) if pos.is_white(pos.board[i+11])
moves.push([i, i-11]) if pos.is_white(pos.board[i-11])
moves.push([i, i+9]) if pos.is_white(pos.board[i+9])
moves.push([i, i-9]) if pos.is_white(pos.board[i-9])
end
end
return moves
end
end
Chess_Search:
class Chess_Search
attr_reader :best_move
#--------------------------------------------------------------------------
# * Search
#--------------------------------------------------------------------------
def search(pos)
@move_gen = Chess_MoveGeneration.new
@best_move = [Chess::NO_SQUARE, Chess::NO_SQUARE]
negamax(pos, 4, -Chess::INFINITY, Chess::INFINITY)
end
#--------------------------------------------------------------------------
# * NegaMax
#--------------------------------------------------------------------------
def negamax(pos, depth, alpha, beta)
# Leaf Node
if(depth == 0)
if(pos.side_to_move == Chess::WHITE)
return pos.score
elsif(pos.side_to_move == Chess::BLACK)
return -pos.score
end
end
# Generate legal moves
moves = []
moves += @move_gen.generateCapture(pos)
moves += @move_gen.generateQuiet(pos)
if(moves.length == 0)
return Chess::DRAW
end
# Browse legal moves
moves.each_index do |i|
pos.make_move( moves[i] )
score = -negamax(pos, depth - 1, -beta, -alpha)
pos.unmake_move()
if(score >= beta)
return beta
end
if(score > alpha)
alpha = score
if(depth == 4)
@best_move = moves[i]
end
end
end
return alpha
end
end
Chess_Position:
class Chess_Position
#--------------------------------------------------------------------------
# * Public Variables
#--------------------------------------------------------------------------
attr_accessor :board
attr_reader :side_to_move
attr_reader :score
#--------------------------------------------------------------------------
# * Start
#--------------------------------------------------------------------------
def initialize
@side_to_move = Chess::WHITE
@board = []
@score = 0
@history = []
@history_capture = []
starting_position
end
#--------------------------------------------------------------------------
# * Start
#--------------------------------------------------------------------------
def clear
@score = 0
# 120
i = 0
while(i < 120)
@board[i] = Chess::OFF_BOARD
i += 1
end
# Real 64 board
i = 0
while(i < 64)
@board[sq120(i)] = Chess::NO_PIECE
i += 1
end
end
#--------------------------------------------------------------------------
# * Move
#--------------------------------------------------------------------------
def make_move(move)
# Update game score
@score -= Chess::PVALUE[@board[move[1]]]
# Record history
@history.push(move)
@history_capture.push(@board[move[1]])
# Move piece
@board[move[1]] = @board[move[0]]
@board[move[0]] = Chess::NO_PIECE
@side_to_move = !@side_to_move
end
#--------------------------------------------------------------------------
# * Undo Move
#--------------------------------------------------------------------------
def unmake_move()
move = @history.pop
captured = @history_capture.pop
# Refactor game score
@score += Chess::PVALUE[captured]
# Move back piece
@board[move[0]] = @board[move[1]]
@board[move[1]] = captured
@side_to_move = !@side_to_move
end
#--------------------------------------------------------------------------
# * Color
#--------------------------------------------------------------------------
def is_white(piece)
(piece >= Chess::W_PAWN && piece <= Chess::W_KING)
end
def is_black(piece)
(piece >= Chess::B_PAWN && piece <= Chess::B_KING)
end
#--------------------------------------------------------------------------
# * Square 64 => 120
#--------------------------------------------------------------------------
def sq120(s)
x = (s % 8)
y = (s / 8)
21 + y * 10 + x
end
#--------------------------------------------------------------------------
# * Square 120 => 64
#--------------------------------------------------------------------------
def sq64(s)
s -= 21;
x = (s % 10)
y = (s / 10)
y * 8 + x
end
#--------------------------------------------------------------------------
# * Starting position
#--------------------------------------------------------------------------
def starting_position
clear
# White
@board[Chess::A1] = Chess::W_ROOK
@board[Chess::B1] = Chess::W_KNIGHT
@board[Chess::C1] = Chess::W_BISHOP
@board[Chess::D1] = Chess::W_QUEEN
@board[Chess::E1] = Chess::W_KING
@board[Chess::F1] = Chess::W_BISHOP
@board[Chess::G1] = Chess::W_KNIGHT
@board[Chess::H1] = Chess::W_ROOK
@board[Chess::A2] = Chess::W_PAWN
@board[Chess::B2] = Chess::W_PAWN
@board[Chess::C2] = Chess::W_PAWN
@board[Chess::D2] = Chess::W_PAWN
@board[Chess::E2] = Chess::W_PAWN
@board[Chess::F2] = Chess::W_PAWN
@board[Chess::G2] = Chess::W_PAWN
@board[Chess::H2] = Chess::W_PAWN
# Black
@board[Chess::A8] = Chess::B_ROOK
@board[Chess::B8] = Chess::B_KNIGHT
@board[Chess::C8] = Chess::B_BISHOP
@board[Chess::D8] = Chess::B_QUEEN
@board[Chess::E8] = Chess::B_KING
@board[Chess::F8] = Chess::B_BISHOP
@board[Chess::G8] = Chess::B_KNIGHT
@board[Chess::H8] = Chess::B_ROOK
@board[Chess::A7] = Chess::B_PAWN
@board[Chess::B7] = Chess::B_PAWN
@board[Chess::C7] = Chess::B_PAWN
@board[Chess::D7] = Chess::B_PAWN
@board[Chess::E7] = Chess::B_PAWN
@board[Chess::F7] = Chess::B_PAWN
@board[Chess::G7] = Chess::B_PAWN
@board[Chess::H7] = Chess::B_PAWN
end
end
Scene_Chess: (VXA Version)
#==============================================================================
# ** Scene_Chess
#------------------------------------------------------------------------------
# This class performs chess game UI and AI
#==============================================================================
class Scene_Chess < Scene_Base
#--------------------------------------------------------------------------
# * Start Processing
#--------------------------------------------------------------------------
def start
super
@position = Chess_Position.new
@move_gen = Chess_MoveGeneration.new
@search = Chess_Search.new
@selected_square = @position.sq64(Chess::E2)
@from_square = Chess::NO_SQUARE
load_piece_sprite
create_chessboard_sprite
create_piece_sprite
redraw_pieces
end
#--------------------------------------------------------------------------
# * Make move
#--------------------------------------------------------------------------
def make_move(from, to)
from = @position.sq120(from)
to = @position.sq120(to)
move = [from, to]
move_legal = @move_gen.move_exists(@position, move)
if(move_legal)
# Make player move
@position.make_move(move)
redraw_pieces
# Pick computer move
@search.search(@position)
# Make move
@position.make_move(@search.best_move)
redraw_pieces
dx = (@position.sq64(@search.best_move[1]) % 8)
dy = (@position.sq64(@search.best_move[1]) / 8)
@last_move_sprite.x = dx * @square_size + @board_padding
@last_move_sprite.y = dy * @square_size
@last_move_sprite.visible = true
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Move cursor
if(Input.trigger?(:UP))
@selected_square -= 8
elsif(Input.trigger?(:RIGHT))
@selected_square += 1
elsif(Input.trigger?(:LEFT))
@selected_square -= 1
elsif(Input.trigger?(:DOWN))
@selected_square += 8
end
@selected_square = 0 if(@selected_square < 0)
@selected_square = 63 if(@selected_square > 63)
# Enter
if(Input.trigger?(:C))
if(@from_square != Chess::NO_SQUARE)
make_move(@from_square, @selected_square)
@from_square = Chess::NO_SQUARE
else
@from_square = @selected_square
end
end
# Position sprite
@cursor_sprite.x = @square_size * (@selected_square % 8) + @board_padding
@cursor_sprite.y = @square_size * (@selected_square / 8)
@from_sprite.x = @square_size * (@from_square % 8) + @board_padding
@from_sprite.y = @square_size * (@from_square / 8)
super
end
#--------------------------------------------------------------------------
# * create_piece_sprite
#--------------------------------------------------------------------------
def create_piece_sprite
@piece_sprite = Sprite.new
@piece_sprite.x = @board_padding
@piece_sprite.y = 0
@piece_sprite.z = 150
@piece_sprite.bitmap = Bitmap.new(@board_size, @board_size)
end
#--------------------------------------------------------------------------
# * Redraw piece
#--------------------------------------------------------------------------
def redraw_pieces
@piece_sprite.bitmap.clear
x = 0; y = 0;
while(y < 8)
while(x < 8)
square64 = y * 8 + x
square120 = @position.sq120(square64)
piece = @position.board[square120]
if(piece != Chess::NO_PIECE)
dx = @square_size * x
dy = @square_size * y
rect = Rect.new(0, 0, @board_size, @board_size)
@piece_sprite.bitmap.blt(dx, dy, @piece_bitmaps[piece], rect)
end
x += 1
end
x = 0
y += 1
end
end
#--------------------------------------------------------------------------
# * Load Piece Sprite
#--------------------------------------------------------------------------
def load_piece_sprite
@piece_bitmaps = []
@piece_bitmaps[Chess::W_PAWN] = Bitmap.new("ChessPieces/white_pawn.png")
@piece_bitmaps[Chess::W_ROOK] = Bitmap.new("ChessPieces/white_rook.png")
@piece_bitmaps[Chess::W_KNIGHT] = Bitmap.new("ChessPieces/white_knight.png")
@piece_bitmaps[Chess::W_BISHOP] = Bitmap.new("ChessPieces/white_bishop.png")
@piece_bitmaps[Chess::W_QUEEN] = Bitmap.new("ChessPieces/white_queen.png")
@piece_bitmaps[Chess::W_KING] = Bitmap.new("ChessPieces/white_king.png")
@piece_bitmaps[Chess::B_PAWN] = Bitmap.new("ChessPieces/black_pawn.png")
@piece_bitmaps[Chess::B_ROOK] = Bitmap.new("ChessPieces/black_rook.png")
@piece_bitmaps[Chess::B_KNIGHT] = Bitmap.new("ChessPieces/black_knight.png")
@piece_bitmaps[Chess::B_BISHOP] = Bitmap.new("ChessPieces/black_bishop.png")
@piece_bitmaps[Chess::B_QUEEN] = Bitmap.new("ChessPieces/black_queen.png")
@piece_bitmaps[Chess::B_KING] = Bitmap.new("ChessPieces/black_king.png")
end
#--------------------------------------------------------------------------
# * Create chessboard sprite
#--------------------------------------------------------------------------
def create_chessboard_sprite
Graphics.resize_screen(640, 480)
# Size constants
@board_size = 480
@board_padding = (640 - @board_size) / 2
@square_size = @board_size / 8
# Create board sprite
@board_gfx = Sprite.new
@board_gfx.z = 10
@board_gfx.x = @board_padding
@board_gfx.bitmap = Bitmap.new(@board_size, @board_size)
y = 0
while(y < 8)
x = 0
while(x < 8)
x2 = x * @square_size
y2 = y * @square_size
if((x + y) % 2 == 0)
col = Color.new(255, 255, 255)
else
col = Color.new(80, 30, 0)
end
@board_gfx.bitmap.fill_rect(x2, y2, @square_size, @square_size, col)
x += 1
end
y += 1
end
# Create square cursor sprite
@cursor_sprite = Sprite.new
@cursor_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@cursor_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 100))
@cursor_sprite.z = 50
# Create from_square sprite
@from_sprite = Sprite.new
@from_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@from_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(100, 255, 100))
@from_sprite.z = 51
# Create last_move_to sprite
@last_move_sprite = Sprite.new
@last_move_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@last_move_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(200, 200, 100))
@last_move_sprite.z = 51
@last_move_sprite.visible = false
end
#--------------------------------------------------------------------------
# * Termination Processing
#--------------------------------------------------------------------------
def terminate
super
end
end
Scene_Chess (VX Version)
[code]
#==============================================================================
# ** Scene_Chess
#------------------------------------------------------------------------------
# This class performs chess game UI and AI
#==============================================================================
class Scene_Chess < Scene_Base
#--------------------------------------------------------------------------
# * Start Processing
#--------------------------------------------------------------------------
def start
super
Graphics.resize_screen(640, 480)
@position = Chess_Position.new
@move_gen = Chess_MoveGeneration.new
@search = Chess_Search.new
@selected_square = @position.sq64(Chess::E2)
@from_square = Chess::NO_SQUARE
load_piece_sprite
create_chessboard_sprite
create_piece_sprite
redraw_pieces
end
#--------------------------------------------------------------------------
# * Make move
#--------------------------------------------------------------------------
def make_move(from, to)
from = @position.sq120(from)
to = @position.sq120(to)
move = [from, to]
move_legal = @move_gen.move_exists(@position, move)
if(move_legal)
# Make player move
@position.make_move(move)
redraw_pieces
# Pick computer move
@search.search(@position)
# Make move
@position.make_move(@search.best_move)
redraw_pieces
dx = (@position.sq64(@search.best_move[1]) %
dy = (@position.sq64(@search.best_move[1]) /
@last_move_sprite.x = dx * @square_size + @board_padding
@last_move_sprite.y = dy * @square_size
@last_move_sprite.visible = true
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Move cursor
if(Input.trigger?(Input::UP))
@selected_square -= 8
elsif(Input.trigger?(Input::RIGHT))
@selected_square += 1
elsif(Input.trigger?(Input::LEFT))
@selected_square -= 1
elsif(Input.trigger?(Input::DOWN))
@selected_square += 8
end
@selected_square = 0 if(@selected_square < 0)
@selected_square = 63 if(@selected_square > 63)
# Enter
if(Input.trigger?(Input::C))
if(@from_square != Chess::NO_SQUARE)
make_move(@from_square, @selected_square)
@from_square = Chess::NO_SQUARE
else
@from_square = @selected_square
end
end
# Position sprite
@cursor_sprite.x = @square_size * (@selected_square %
+ @board_padding
@cursor_sprite.y = @square_size * (@selected_square /
@from_sprite.x = @square_size * (@from_square %
+ @board_padding
@from_sprite.y = @square_size * (@from_square /
end
#--------------------------------------------------------------------------
# * create_piece_sprite
#--------------------------------------------------------------------------
def create_piece_sprite
@piece_sprite = Sprite.new
@piece_sprite.x = @board_padding
@piece_sprite.y = 0
@piece_sprite.z = 150
@piece_sprite.bitmap = Bitmap.new(@board_size, @board_size)
end
#--------------------------------------------------------------------------
# * Redraw piece
#--------------------------------------------------------------------------
def redraw_pieces
@piece_sprite.bitmap.clear
x = 0; y = 0;
while(y <
while(x <
square64 = y * 8 + x
square120 = @position.sq120(square64)
piece = @position.board[square120]
if(piece != Chess::NO_PIECE)
dx = @square_size * x
dy = @square_size * y
rect = Rect.new(0, 0, @board_size, @board_size)
@piece_sprite.bitmap.blt(dx, dy, @piece_bitmaps[piece], rect)
end
x += 1
end
x = 0
y += 1
end
end
#--------------------------------------------------------------------------
# * Load Piece Sprite
#--------------------------------------------------------------------------
def load_piece_sprite
@piece_bitmaps = []
@piece_bitmaps[Chess::W_PAWN] = Bitmap.new("ChessPieces/white_pawn.png")
@piece_bitmaps[Chess::W_ROOK] = Bitmap.new("ChessPieces/white_rook.png")
@piece_bitmaps[Chess::W_KNIGHT] = Bitmap.new("ChessPieces/white_knight.png")
@piece_bitmaps[Chess::W_BISHOP] = Bitmap.new("ChessPieces/white_bishop.png")
@piece_bitmaps[Chess::W_QUEEN] = Bitmap.new("ChessPieces/white_queen.png")
@piece_bitmaps[Chess::W_KING] = Bitmap.new("ChessPieces/white_king.png")
@piece_bitmaps[Chess::B_PAWN] = Bitmap.new("ChessPieces/black_pawn.png")
@piece_bitmaps[Chess::B_ROOK] = Bitmap.new("ChessPieces/black_rook.png")
@piece_bitmaps[Chess::B_KNIGHT] = Bitmap.new("ChessPieces/black_knight.png")
@piece_bitmaps[Chess::B_BISHOP] = Bitmap.new("ChessPieces/black_bishop.png")
@piece_bitmaps[Chess::B_QUEEN] = Bitmap.new("ChessPieces/black_queen.png")
@piece_bitmaps[Chess::B_KING] = Bitmap.new("ChessPieces/black_king.png")
end
#--------------------------------------------------------------------------
# * Create chessboard sprite
#--------------------------------------------------------------------------
def create_chessboard_sprite
# Size constants
@board_size = 480
@board_padding = (640 - @board_size) / 2
@square_size = @board_size / 8
# Create board sprite
@board_gfx = Sprite.new
@board_gfx.z = 10
@board_gfx.x = @board_padding
@board_gfx.bitmap = Bitmap.new(@board_size, @board_size)
y = 0
while(y <
x = 0
while(x <
x2 = x * @square_size
y2 = y * @square_size
if((x + y) % 2 == 0)
col = Color.new(255, 255, 255)
else
col = Color.new(80, 30, 0)
end
@board_gfx.bitmap.fill_rect(x2, y2, @square_size, @square_size, col)
x += 1
end
y += 1
end
# Create square cursor sprite
@cursor_sprite = Sprite.new
@cursor_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@cursor_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 100))
@cursor_sprite.z = 50
# Create from_square sprite
@from_sprite = Sprite.new
@from_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@from_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(100, 255, 100))
@from_sprite.z = 51
# Create last_move_to sprite
@last_move_sprite = Sprite.new
@last_move_sprite.bitmap = Bitmap.new(@square_size, @square_size)
@last_move_sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(200, 200, 100))
@last_move_sprite.z = 51
@last_move_sprite.visible = false
end
#--------------------------------------------------------------------------
# * Termination Processing
#--------------------------------------------------------------------------&