RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
[VX] Chess Engine v2

0 Members and 1 Guest are viewing this topic.

***
Rep:
Level 39
N
2014 Zero to Hero
Chess Engine
For RPG Maker VX
by Abigaila



What is this?
Spoiler for:
This is a chess engine for RPG Maker.



How to use? IMPORTANT
Spoiler for:
1. Download the attached Chess.dll and place it in your game directory. Make sure the name of the file doesn't change. This is the actual engine that does the thinking.

2a. Install the interface script like you would any other script, invoke it by calling Scene_Chess

-- Or --

2b. You can use the chess engine for some other functionality, or make your own interface. Here is a list of commands. (You must have an understanding of Win32API.)
Code: [Select]
1. Starting position: Win32API.new("Chess.dll", "reset", "", "V")
2. Does a move exist?: Win32API.new("Chess.dll", "move_exists", ['I','I'], "I")
3. Make a move: Win32API.new("Chess.dll", "do_move", ['I','I'], "I")
4. Take back move: Win32API.new("Chess.dll", "undo_move", "", "I")
5. Computer moves: Win32API.new("Chess.dll", "best_move", "", "L")
6. Get piece on given square (or empty): Win32API.new("Chess.dll", "get_square", "I", "I")
7. Get side to move: Win32API.new("Chess.dll", "side_to_move", "", "I")
@console = Win32API.new("Chess.dll", "console", "", "V")




Script (graphical interface)
Spoiler for:
Code: [Select]
#==============================================================================
# ** Scene_Chess
#------------------------------------------------------------------------------
#  This class performs chess game UI and AI
#==============================================================================

class Scene_Chess < Scene_Base
  #--------------------------------------------------------------------------
  # * Constants
  #--------------------------------------------------------------------------
  WHITE = 0; BLACK = 1;
 
  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;
  EMPTY = 12;
 
  BOARD_SIZE = 480
  SQ_SIZE = BOARD_SIZE/8
  #--------------------------------------------------------------------------
  # * Start Processing
  #--------------------------------------------------------------------------
  def start
    super
    setup_engine
    setup_graphics
   
    @new_game.call()
    #@console.call()
    refresh
  end
     
  #--------------------------------------------------------------------------
  # * Setup Engine
  #--------------------------------------------------------------------------                     
  def setup_engine
    @new_game = Win32API.new("Chess.dll", "reset", "", "V")
    @move_exists = Win32API.new("Chess.dll", "move_exists", ['I','I'], "I")
    @do_move = Win32API.new("Chess.dll", "do_move", ['I','I'], "I")
    @undo_move = Win32API.new("Chess.dll", "undo_move", "", "I")
    @best_move = Win32API.new("Chess.dll", "best_move", "", "L")
    @get_square = Win32API.new("Chess.dll", "get_square", "I", "I")
    @side_to_move = Win32API.new("Chess.dll", "side_to_move", "", "I")
    @console = Win32API.new("Chess.dll", "console", "", "V")
  end
     
  #--------------------------------------------------------------------------
  # * Setup Graphics
  #--------------------------------------------------------------------------                     
  def setup_graphics
    Graphics.resize_screen(640, 480)
   
    # Cursor
    @cursor = 55
    @cursor_spr = Sprite.new
    @cursor_spr.z = 50
    @cursor_spr.opacity = 200
    @cursor_spr.bitmap = Bitmap.new(SQ_SIZE, SQ_SIZE)
    @cursor_spr.bitmap.fill_rect(0, 0, SQ_SIZE, SQ_SIZE, Color.new(255,255,100))
   
    # From (blue indicating which piece has been selected)
    @from = -1
    @from_spr = Sprite.new
    @from_spr.visible = false
    @from_spr.z = 50
    @from_spr.opacity = 255
    @from_spr.bitmap = Bitmap.new(SQ_SIZE, SQ_SIZE)
    @from_spr.bitmap.fill_rect(0, 0, SQ_SIZE, SQ_SIZE, Color.new(50,100,255))
   
    # Board grid bitmap
    @board_spr = Sprite.new
    @board_spr.bitmap = Bitmap.new(BOARD_SIZE, BOARD_SIZE)
   
    i = 0;
    while(i < 64)
      odd = (i/8+i%8) % 2
      odd = 1 - odd;
     
      x = SQ_SIZE * (i % 8)
      y = SQ_SIZE * (i / 8)
      color = Color.new(100+155*odd, 140+115*odd, 140+115*odd)
     
      @board_spr.bitmap.fill_rect(x, y, SQ_SIZE, SQ_SIZE, color);
      i+=1;
    end
   
    # Pieces bitmap
    @piece_bitmap = Bitmap.new("pieces.png")
   
    # Pieces sprite
    @piece_sprite = Sprite.new()
    @piece_sprite.x = 0; @piece_sprite.y = 0;
    @piece_sprite.z = 100;
    @piece_sprite.bitmap = Bitmap.new(BOARD_SIZE, BOARD_SIZE)
  end
 
 
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    super
   
    # Enter pressed
    if(Input.trigger?(Input::C))
      move_is_legal = move_exists?(@from, @cursor)
     
      if(move_is_legal || !square_selectable?)
        if(move_is_legal)
          # Player move
          do_move(@from, @cursor)
          refresh
          Graphics.update
         
          # Computer move
          best_move
          refresh
        else
          @from = -1;
          @from_spr.visible = false;
        end
       
      else #square holds your piece
        @from = @cursor
       
        @from_spr.x = SQ_SIZE * (@from % 8)
        @from_spr.y = SQ_SIZE * (@from / 8)
        @from_spr.visible = true;
      end
    end
   
    # Undo pressed
    if(Input.trigger?(Input::B))
      @undo_move.call()
      @undo_move.call()
      refresh
      Graphics.update
    end
   
    # Move cursor
    @cursor -= 1 if(Input.trigger?(Input::LEFT))
    @cursor += 1 if(Input.trigger?(Input::RIGHT))
    @cursor -= 8 if(Input.trigger?(Input::UP))
    @cursor += 8 if(Input.trigger?(Input::DOWN))
   
    @cursor_spr.x = SQ_SIZE * (@cursor % 8)
    @cursor_spr.y = SQ_SIZE * (@cursor / 8)
  end
 
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    @piece_sprite.bitmap.clear
   
    i = 0
    while(i < 64)
      pce_id = @get_square.call(i)
     
      if(pce_id != EMPTY)
        x = SQ_SIZE * (i % 8)
        y = SQ_SIZE * (i / 8)
     
        col = pce_id > W_KING ? 1 : 0
        pce = pce_id - (col * B_PAWN)
        source = Rect.new(pce*60, col*60, 60, 60)
     
        @piece_sprite.bitmap.blt(x, y, @piece_bitmap, source);
      end
     
      i += 1
    end
  end
 
  #--------------------------------------------------------------------------
  # * Do  Move
  #--------------------------------------------------------------------------
  def do_move(from, to)
    @do_move.call(from, to)
   
    @from_spr.visible = true
    @from_spr.x = (to % 8) * SQ_SIZE;
    @from_spr.y = (to / 8) * SQ_SIZE;
  end
 
  #--------------------------------------------------------------------------
  # * Do Best Move
  #--------------------------------------------------------------------------
  def best_move()
    best_move = @best_move.call
     
    # From and To are stored in bits
    from = 63 & (best_move >> 6);
    to = 63 & best_move;
     
    do_move(from, to)
  end
 
  #--------------------------------------------------------------------------
  # * Move Exists
  #--------------------------------------------------------------------------
  def move_exists?(from, to)
    result = @move_exists.call(from, to)
    return result == 1
  end
 
  #--------------------------------------------------------------------------
  # * Square is Selectable
  #--------------------------------------------------------------------------
  def square_selectable?
    if(@get_square.call(@cursor) == EMPTY)
      return false
     
    elsif(@get_square.call(@cursor) <= W_KING && @side_to_move.call() == WHITE)
      return true
     
    elsif(@get_square.call(@cursor) >= B_PAWN && @side_to_move.call() == BLACK)
      return true
     
    else
      return false
    end
  end
end





DLL-free version (V1):
This version is made entirely with RPG Maker scripts and doesn't rely on a dll. It is much weaker as a player though.
Spoiler for:
Chess_Constants:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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:
Code: [Select]
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)
Code: [Select]
#==============================================================================
# ** 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]) % 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
    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 % 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)
  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
    # 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
  #--------------------------------------------------------------------------&
« Last Edit: May 30, 2014, 10:46:57 PM by Abigaila »

*
RMRK's dad
Rep:
Level 86
You know, I think its all gonna be okay.
For going the distance for a balanced breakfast.Project of the Month winner for June 2009For being a noted contributor to the RMRK Wiki2013 Best WriterSilver Writing ReviewerSecret Santa 2013 Participant
Are you shitting me? You're shitting me. If his was for VX I would totally lose my shit. As it stands im impressed. Ahh, I need to get a new computer  so I can try this out!
:tinysmile:

***
Rep:
Level 39
N
2014 Zero to Hero
Are you shitting me? You're shitting me. If his was for VX I would totally lose my shit. As it stands im impressed. Ahh, I need to get a new computer  so I can try this out!

:D I'm not shitting you! Note however, that I haven't gotten around to the intricacies of check, checkmate, castling etc. yet, thus it's in progress.

Also the AI is fairly simple, but that too will be improved with time :)

*
RMRK's dad
Rep:
Level 86
You know, I think its all gonna be okay.
For going the distance for a balanced breakfast.Project of the Month winner for June 2009For being a noted contributor to the RMRK Wiki2013 Best WriterSilver Writing ReviewerSecret Santa 2013 Participant
Dude. When you have it down I will name my son's left foot after you to convert it to VX. It's  EXACTLY  whT I want!
:tinysmile:

***
Rep:
Level 39
N
2014 Zero to Hero
Dude. When you have it down I will name my son's left foot after you to convert it to VX. It's  EXACTLY  whT I want!

Haha :D I can probably convert it to VX, it shouldn't be much work at all. It doesn't depend on the standard scripts at all other than the scene.

*
Rep:
Level 72
~Few people understand the beauty of the night~
2014 Best Topic
Hmm, I found one problem right off the bat; It requires the VXA RTP to run. You need to fix that =p

Other than that, I like the concept, and if it actually has somewhat decent AI, then I am impressed :)
Download http://a.tumblr.com/tumblr_lm5v281q6E1qde50fo1.mp3

***
Rep:
Level 39
N
2014 Zero to Hero
Hmm, I found one problem right off the bat; It requires the VXA RTP to run. You need to fix that =p

Other than that, I like the concept, and if it actually has somewhat decent AI, then I am impressed :)

Thanks for telling me. Including the RTP will make the file enormous though. I'll see if I can remove dependencies on RTP.

Added VX Version

*
Rep:
Level 72
~Few people understand the beauty of the night~
2014 Best Topic
You actually don't have to include the whole RTP. Do you know how to do this? If no, I'll see if I can find the tutorial I used to use, and if it's gone, I'll just write up a new one.. It's pretty easy to do, and I'm sure you'll benefit from it a bit :)
Download http://a.tumblr.com/tumblr_lm5v281q6E1qde50fo1.mp3

***
Rep:
Level 39
N
2014 Zero to Hero
You actually don't have to include the whole RTP. Do you know how to do this? If no, I'll see if I can find the tutorial I used to use, and if it's gone, I'll just write up a new one.. It's pretty easy to do, and I'm sure you'll benefit from it a bit :)

That would be awesome

*
Rep:
Level 72
~Few people understand the beauty of the night~
2014 Best Topic
I do apologize that it's on another forum, but this is the guide I used when I was new to RMXP, and it was really easy for me to follow, so I tend to suggest this to new game makers..

http://forum.chaos-project.com/index.php/topic,41.0.html
Download http://a.tumblr.com/tumblr_lm5v281q6E1qde50fo1.mp3

***
Rep:
Level 39
N
2014 Zero to Hero
New version up. It's now much stronger and fully functional with castling and check working.

**
Rep:
Level 73
RMRK Junior
it seems the dll can't be used in Windows XP