Chess Trap Variant

I’m planning to run a Dungeon World campaign based on a classic D&D Super Endless Quest book called The Ghost Tower which, in turn, is based on a classic D&D module called The Ghost Tower of Inverness.

There is a trap in this book based on Chess, where the party are each

Here’s the problem:

  • I’ve already stolen the idea for this trap for another game.
  • I made it a series of rooms, each room representing a square on the chessboard.
  • I even had zombies representing opponent chess pieces wandering from room to room.

I still want to include this trap, but I’m struggling with how to make it fresh for the players. They’re probably going to recognize it for what it is: a chessboard. But even if they do, I want them to have fun with it. I think I can play on their expectations and throw them for a loop.

How can I change the trap to do this?

Why can’t we combine thousands of computers and dynamic programming to solve chess once and for all?

It takes 3000 years for a single computer to solve chess. But if we keep adding a computer to solving the problem, wouldn’t that divide the time it takes by 1/N for each computer we add? For example if we launched maybe tens of thousands of smaller computers, maybe using a cloud platform like AWS, and had each computer work on a small sub-problem of chess, store the results in a cloud database so the other computers know what subproblems have already been solved or are being worked on, we could solve chess in less than a week.

Why wouldn’t this work? And if it could work why has no one attempted this yet?

How to get the address of a nearby square on a chess board?

I’m making a chess game from scratch and I got stuck.

So far I have all my figures placed, I have the positions set, I’ve already done the collision detection and everything.

When I click the figure that is in position A1 for example, I want to make two green rectangles at positions A2 and A3, and they will be used to make the figure move.

Is there a method for to add 1 to the string “A1” to form the string “A2” or something? Because thats all I really need right now.

Also if there’s a more clever way to make the positions please let me know.

As an example, here is how I currently look up my display positions using the A1, A2 etc. location codes:

let positions = {         A1 : [10, 710],B1 : [110, 710],C1 : [210, 710],D1 : [310, 710],E1 : [410, 710],F1 : [510, 710],G1 : [610, 710],H1 : [710, 710],         A2 : [10, 610],B2 : [110, 610],C2 : [210, 610],D2 : [310, 610],E2 : [410, 610],F2 : [510, 610],G2 : [610, 610],H2 : [710, 610],         A3 : [10, 510],B3 : [110, 510],C3 : [210, 510],D3 : [310, 510],E3 : [410, 510],F3 : [510, 510],G3 : [610, 510],H3 : [710, 510],         A4 : [10, 410],B4 : [110, 410],C4 : [210, 410],D4 : [310, 410],E4 : [410, 410],F4 : [510, 410],G4 : [610, 410],H4 : [710, 410],         A5 : [10, 310],B5 : [110, 310],C5 : [210, 310],D5 : [310, 310],E5 : [410, 310],F5 : [510, 310],G5 : [610, 310],H5 : [710, 310],         A6 : [10, 210],B6 : [110, 210],C6 : [210, 210],D6 : [310, 210],E6 : [410, 210],F6 : [510, 210],G6 : [610, 210],H6 : [710, 210],         A7 : [10, 110],B7 : [110, 110],C7 : [210, 110],D7 : [310, 110],E7 : [410, 110],F7 : [510, 110],G7 : [610, 110],H7 : [710, 110],         A8 : [10, 10], B8 : [110, 10], C8 : [210, 10], D8 : [310, 10], E8 : [410, 10], F8 : [510, 10], G8 : [610, 10], H8 : [710, 10],     } 

the [0] of the arrays is x and the [1] is y, and that’s also how I placed the figures.

sturdy, metallic chess clock as carry-on baggage

I am an amateur chess player and I am considering flying from the US to Europe with the following chess clock:

https://www.amazon.com/Chronos-GX-Touch-Chess-Clock/dp/B0015V3ZZ0

I am a concerned that the clock is a bit “scary-looking”. It’s also quite sturdy and made of metal (aluminum) so I guess (my Physics is a bit rusty) that it’s like a Faraday cage with mostly empty space inside it (basically some tiny electronics, some wires and two AA batteries). As such, I am not sure how it shows / registers on the equipment they use and whether it might cause the operators to be concerned.

Is it safe to assume that I will be allowed to take it with me in the cabin as checked luggage? Or should I perhaps take it with me to the airport already opened so they can inspect what’s inside it? (there is a panel that you need to unscrew to change the batteries or see what’s inside — so a screwdriver is required).

Ruby chess engine gem

This is my first Ruby gem that claims to provide all the rules of the chess game. My goal was to keep this library as simple as possible via OOP principles, and I’d be glad to hear any feedback from you. In particular, I’m interested in code organization and OOP issues

The source code and useful README can be found at GitHub: https://github.com/anikeef/chess_engine

The library consists of 5 main parts:

  • Game class that implements the chess rules
  • Board class that provides data structure for the chess board
  • Piece class and its inheritors, which I’ve tried to make as lightweight as possible
  • MoveValidator module that provides validations methods to Game class
  • Move class that I’ve found useful to make move canceling easier

Also it contains the CLI class for command line interface, available with chess_engine executable.

NOTE: The bishop piece here is called an Elephant because of the russian tradition, but for the rest of the app there should be no difference in naming

Game

require_relative "board" require_relative "move_validator" require_relative "move"  module ChessEngine   class InvalidMove < StandardError; end    ##   # This class provides all the rules for the chess game. It recognizes check,   # checkmate and stalemate. Move validations logic can be found in the   # MoveValidator module, which is included in this class    class Game     attr_accessor :name     attr_reader :current_color     include MoveValidator      def initialize       @board = Board.new       @board.set_default       @current_color = :white       @last_piece = nil       @name = nil       @promotion_coord = false     end      ##     # Accepts the move string in algebraic notation, e.g. "e2e4",     # and applies it to the board.     # Raises InvalidMove if:     # * Game is already over     # * Pawn promotion should be executed first     # * Empty square is chosen     # * Player tries to move piece of the opponent     # * Move is invalid (checks via the MoveValidator module)     # * Move is fatal (king is attacked after the move)     #     # After successfull move, the method changes the current player or     # goes into "A pawn needs promotion" state, which can be checked by     # #needs_promotion? method      def move(string)       from, to = Game.string_to_coords(string)       piece = @board.at(from)       raise InvalidMove, "Game is over" if over?       raise InvalidMove, "#{@current_color} player should execute pawn promotion first" if needs_promotion?       raise InvalidMove, "Empty square is chosen" if piece.nil?       raise InvalidMove, "This is not your piece" unless piece.color == @current_color       raise InvalidMove, "Invalid move" unless valid_moves(from).include?(to)       move = Move.new(@board, from, to)       move.commit       if king_attacked?         move.rollback         raise InvalidMove, "Fatal move"       end        @last_piece = piece       piece.moves_count += 1       @promotion_coord = to and return if piece.pawn? && [7, 0].include?(to[1])       next_player     end      ##     # Returns a piece (or nil if the square is empty) at given coordinates     # === Example     #   g = Game.new     #   g["e2"] #=> <Pawn ...>     #   g["e4"] #=> nil      def [](str)       letters = ("a".."h").to_a       return nil unless /[a-h][1-8]/.match?(str)       @board.at([letters.find_index(str[0]), str[1].to_i - 1])     end      ##     # Returns the board in the nice-looking string      def draw       @board.to_s     end      ##     # Accepts a string with name of the piece.     # Promotes a pawn and changes the current player.     # Raises InvalidMove if promotion is not needed or invalid +class_name+     # has been passed     # === Example     #   game.promotion("queen")      def promotion(class_name)       unless needs_promotion? && ["rook", "knight", "elephant", "queen"].include?(class_name.downcase)         raise InvalidMove, "Invalid promotion"       end       @board.set_at(@promotion_coord, Module.const_get("ChessEngine::#{class_name.capitalize}").new(@current_color))       @promotion_coord = nil       next_player     end      ##     # Accepts a +length+ sybmol :short or :long. Ensures that castling is     # possible and commits appropriate moves. Otherwise, raises InvalidMove      def castling(length)       row = @current_color == :white ? 0 : 7       king = @board.at([4, row])       if length == :short         rook = @board.at([7, row])         line = [5, 6]         moves = [Move.new(@board, [4, row], [6, row]),           Move.new(@board, [7, row], [5, row])]       else         rook = @board.at([0, row])         line = [1, 2, 3]         moves = [Move.new(@board, [4, row], [2, row]),           Move.new(@board, [0, row], [3, row])]       end       raise InvalidMove, "Invalid castling" unless         king && rook && king.moves_count == 0 && rook.moves_count == 0 &&         line.all? { |x| @board.at([x, row]).nil? }        moves.each { |move| move.commit }       if king_attacked?         moves.each { |move| move.rollback }         raise InvalidMove, "Fatal move"       end       @last_piece = nil       next_player     end      ##     # Returns true if game is over      def over?       @board.piece_coordinates(@current_color).all? do |coord|         safe_moves(coord).empty?       end     end      ##     # Checks if pawn promotion is needed      def needs_promotion?       !!@promotion_coord     end      ##     # Returns true if current king is attacked      def check?       king_attacked?     end      private      def king_attacked?       king_coords = @board.king_coords(@current_color)       [[1, 1], [-1, 1], [-1, -1], [1, -1]].each do |move|         next_coords = relative_coords(king_coords, move)         piece = @board.at(next_coords)         return true if piece && piece.color != @current_color && (piece.pawn? || piece.king?)         edge_coords = repeated_move(king_coords, move).last         piece = edge_coords.nil? ? nil : @board.at(edge_coords)         return true if piece && piece.beats_diagonally?       end       [[1, 0], [-1, 0], [0, 1], [0, -1]].each do |move|         next_coords = relative_coords(king_coords, move)         piece = @board.at(next_coords)         return true if piece && piece.king?         edge_coords = repeated_move(king_coords, move).last         piece = edge_coords.nil? ? nil : @board.at(edge_coords)         return true if !piece.nil? && piece.beats_straight?       end       [[1, 2], [2, 1], [1, -2], [-2, 1],       [-1, 2], [2, -1], [-1, -2], [-2, -1]].each do |move|         coords = relative_coords(king_coords, move)         piece = possible_move?(coords) ? @board.at(coords) : nil         return true if !piece.nil? && piece.knight?       end       false     end      ##     # Converts a string in algebraic notation to array of coordinates     # === Example     #   Game.string_to_coord("a2a4") #=> [[0, 1], [0, 3]]      def Game.string_to_coords(string)       string = string.gsub(/\s+/, "").downcase       raise InvalidMove, "Input must look like \"e2 e4\" or \"a6b5\"" unless /^[a-h][1-8][a-h][1-8]$  /.match?(string)       letters = ("a".."h").to_a       [[letters.find_index(string[0]), string[1].to_i - 1],        [letters.find_index(string[2]), string[3].to_i - 1]]     end      def opposite_color       @current_color == :white ? :black : :white     end      def next_player       @current_color = opposite_color     end   end end 

Board

require_relative "piece" require "colorize"  module ChessEngine   ##   # This class provides a data structure for the chess board.   # It is responsible for storing information about pieces positions and moving   # them. It doesn't implement move validations and chess rules,   # so it is possible to make any moves at this level of abstraction.    class Board     ##     # Creates an empty 8x8 board as a 2-dimensional array      def initialize       @board = Array.new(8) { Array.new(8) { nil } }     end      ##     # Sets the initial board position according to the classic chess rules      def set_default       [[:white, 0, 1], [:black, 7, 6]].each do |color, row1, row2|         ["Rook", "Knight", "Elephant", "Queen", "King", "Elephant", "Knight", "Rook"].each.with_index do |class_name, column|           self[column, row1] = Module.const_get("ChessEngine::#{class_name}").new(color)         end          0.upto(7) do |column|           self[column, row2] = Pawn.new(color)         end       end     end      ##     # Returns the piece string on the given position     # === Example     #   at([0, 0]) #=> Rook:white     #   at([3, 3]) #=> nil       def at(coordinates)       return nil unless self.exists_at?(coordinates)       @board[coordinates[0]][coordinates[1]]     end      ##     # Sets the board on given coordinates to +piece+      def set_at(coordinates, piece)       @board[coordinates[0]][coordinates[1]] = piece     end      ##     # Checks if the values of +coordinates+ are between 0 and 7     # === Example     #   exists_at?([0, 0]) #=> true     #   exists_at?([8, -1]) #=> false      def exists_at?(coordinates)       coordinates.all? { |c| c.between?(0, 7) }     end      ##     # Returns a string containing the board in printable format     # (uses colorize gem to paint the squares)      def to_s       string = ""       colors = [[:default, :light_white].cycle, [:light_white, :default].cycle].cycle        7.downto(0) do |row|         string += "#{row + 1} "         colors_cycle = colors.next          0.upto(7) do |column|           piece = self[column, row]           string += piece.nil? ? " " : piece.symbol           string += " "           string[-2..-1] = string[-2..-1].colorize(background: colors_cycle.next)         end         string += "\n"       end        string += "  a b c d e f g h"       string     end      ##     # Moves the value of +from+ coords to +to+ coords. Sets the value of +to+ to nil      def move_piece(from, to)       piece = self.at(from)       self.set_at(from, nil)       self.set_at(to, piece)     end      ##     # Returns the coordinates of the king of given +color+      def king_coords(color)       Board.coordinates_list.find do |coord|         at(coord) && at(coord).king? && at(coord).color == color       end     end      ##     # Returns the array of coordinates where pieces of given +color+ a located      def piece_coordinates(color)       Board.coordinates_list.select do |coord|         piece = at(coord)         !piece.nil? && piece.color == color       end     end      private      def [](column, row)       @board[column][row]     end      def []=(column, row, piece)       @board[column][row] = piece     end      def Board.coordinates_list       list = []       (0..7).each do |x|         (0..7).each { |y| list << [x, y]}       end       list     end   end end 

Piece

module ChessEngine   class Piece     attr_reader :symbol, :color     attr_accessor :moves_count      def initialize(color)       @color = color       @moves_count = 0     end      def inspect       "#{self.class}:#{@color}"     end      def beats_diagonally?       elephant? || queen?     end      def beats_straight?       rook? || queen?     end      ["knight", "king", "pawn", "rook", "queen", "elephant"].each do |piece|       define_method(:"#{piece}?") do         self.class.to_s == "ChessEngine::#{piece.capitalize}"       end     end   end    class Elephant < Piece     def initialize(color)       super       @symbol = (@color == :black) ? "\u25B2" : "\u25B3"     end      def moves       [[1, 1], [1, -1], [-1, 1], [-1, -1]]     end   end    class King < Piece     def initialize(color)       super       @symbol = (@color == :black) ? "\u265A" : "\u2654"     end      def moves       [[0, 1], [0, -1], [1, 0], [-1, 0],       [1, 1], [1, -1], [-1, 1], [-1, -1]]     end   end    class Knight < Piece     def initialize(color)       super       @symbol = (@color == :black) ? "\u265E" : "\u2658"     end      def moves       [[1, 2], [2, 1], [1, -2], [-2, 1],       [-1, 2], [2, -1], [-1, -2], [-2, -1]]     end   end    class Pawn < Piece     attr_reader :direction      def initialize(color)       super       @symbol = (@color == :black) ? "\u265F" : "\u2659"       @direction = (@color == :white) ? 1 : -1     end   end    class Queen < Piece     def initialize(color)       super       @symbol = (@color == :black) ? "\u265B" : "\u2655"     end      def moves       [[0, 1], [0, -1], [1, 0], [-1, 0],       [1, 1], [1, -1], [-1, 1], [-1, -1]]     end   end    class Rook < Piece     def initialize(color)       super       @symbol = (@color == :black) ? "\u265C" : "\u2656"     end      def moves       [[1, 0], [0, 1], [-1, 0], [0, -1]]     end   end end 

MoveValidator

module ChessEngine   ##   # This module contains all the methods needed to check if   # some move is valid or not. It is included in the Game class and so uses   # some of its attributes: board, current_color and last_piece (for en passant only)    module MoveValidator      ## Excludes from valid_moves all fatal moves      def safe_moves(from)       valid_moves(from).reject { |move| fatal_move?(from, move) }     end      ##     # Returns an array of valid moves for a piece at the given position.     # Note: this method doesn't exclude moves that lead current king to be attacked     # (See +#safe_moves+ method)      def valid_moves(from)       piece = @board.at(from)       if piece.king? || piece.knight?         piece.moves.map do |move|           to = relative_coords(from, move)           to if possible_move?(to)         end.compact       elsif piece.pawn?         pawn_valid_moves(from)       else         valid_moves_recursive(from)       end     end      ##     # Returns an array of coordinates that can be reached by recursively     # applying the given +move+, starting from the +from+ coordinates      private      def repeated_move(from, move, valid_moves = [])       coordinates = relative_coords(from, move)       return valid_moves unless possible_move?(coordinates)       return valid_moves << coordinates unless @board.at(coordinates).nil?       repeated_move(coordinates, move, valid_moves << coordinates)     end      ##     # Returns coordinates that will be reached after applying the +move+,     # starting from the +from+ coordinates      def relative_coords(from, move)       [from[0] + move[0], from[1] + move[1]]     end      ##     # Returns true if:     # * The 8x8 board exists at given coordinates     # * Board at given coordinates is empty or it contains a piece with the same     #   color as the current_color      def possible_move?(coordinates)       if @board.exists_at?(coordinates)         piece = @board.at(coordinates)         return (piece.nil? || piece.color != @current_color)       end       return false     end      ##     # Returns true if the current king is attacked after the given move      def fatal_move?(from, to)       is_fatal = false       move = Move.new(@board, from, to)       move.commit       is_fatal = true if king_attacked?       move.rollback       is_fatal     end      def pawn_valid_moves(from)       pawn = @board.at(from)       direction = pawn.direction       moves = []       next_coords = relative_coords(from, [0, direction])       jump_coords = relative_coords(from, [0, direction * 2])       take_coords = [relative_coords(from, [1, direction]),         relative_coords(from, [-1, direction])]       if @board.exists_at?(next_coords) && @board.at(next_coords).nil?         moves << next_coords         moves << jump_coords unless pawn.moves_count > 0 || @board.at(jump_coords)       end       take_coords.each do |coords|         moves << coords if @board.at(coords) && @board.at(coords).color != pawn.color       end       en_passant_coords(from) ? moves << en_passant_coords(from) : moves     end      ##     # Returns additional valid coordinates for the pawn if available      def en_passant_coords(from)       pawn = @board.at(from)       [1, -1].each do |x|         next_coords = [from[0] + x, from[1]]         next_piece = @board.at(next_coords)         if next_piece.class == Pawn && next_piece == @last_piece &&           next_piece.moves_count == 1 && from[1].between?(3, 4)             return [from[0] + x, from[1] + pawn.direction]         end       end       nil     end      ##     # This method is used by #valid_moves for pieces like Queen, Rook and Elephant,     # that should move recursively      def valid_moves_recursive(from)       piece = @board.at(from)       piece.moves.inject([]) do |valid_moves, move|         valid_moves.push(*repeated_move(from, move))       end     end   end end 

Move

module ChessEngine   ##   # This class is made to make move canceling easier if something goes wrong.    class Move     def initialize(board, from, to)       @board = board       @from = from       @to = to       @original_squares = []       @original_squares << {coord: from, piece: board.at(from)}       @original_squares << {coord: to, piece: board.at(to)}       if en_passant?         @en_passant_coord = [to[0], from[1]]         @original_squares << {coord: @en_passant_coord, piece: board.at(@en_passant_coord)}       end     end      ##     # Applies the move to the board      def commit       if en_passant?         @board.set_at(@en_passant_coord, nil)       end       @board.move_piece(@from, @to)     end      ##     # Moves pieces back and returns the board to the previous state      def rollback       @original_squares.each do |square|         @board.set_at(square[:coord], square[:piece])       end     end      private      def en_passant?       @board.at(@from).pawn? && @from[0] != @to[0] && @board.at(@to).nil?     end   end end ``` 

Python Chess Game

I’m developing chess in python, and I’ve decided to make everything text-based before creating a GUI because it’d be my first time doing the latter. I haven’t got around to the actual gameplay, but I’ve modeled the possible movement of any piece.

Note that I cannot implement En Passant and castling without turn data.

from time import sleep  class Config:     DEMTIME = .8  # seconds     types = {'min': 1, 'miniature': 3, 'small': 5, 'default': 8, 'extended': 11, 'large': 15, 'massive': 20, 'max': 26}     letters = tuple('abcdefghijklmnopqrstuvwxyz')     white_pieces = {'Pawn' : "♙", 'Rook' : "♖", 'Knight' : "♘", 'Bishop' : "♗", 'King' : "♔", 'Queen' : "♕" }     black_pieces = {'Pawn' : "♟", 'Rook' : "♜", 'Knight' : "♞", 'Bishop' : "♝", 'King' : "♚", 'Queen' : "♛" }     board = 'UNINITIALIZED'     b_len = 'UNINITIALIZED'      @classmethod     def new_board(cls, btype='default'):         def size(x):             return [['___' for _ in range(x)] for _ in range(x)], x          s = False          if btype is not None:             btype = btype.lower()              if 'custom' in btype:                 btype = int(btype.replace('custom', '').strip())                 if 1 <= btype <= 26:                     cls.board, cls.b_len = size(btype)                     s = True                 else:                     btype = None                     cls.new_board(btype)             elif btype in cls.types:                 cls.board, cls.b_len = size(cls.types[btype])                 s = True             else:                 print(f'Unable to initialize board of unknown type {btype}')          else:             print('Unable to initalize board with a size lower than 1 or greater than 26')          if s: cls.print_board()      @classmethod     def print_board(cls):         if Config.b_len != 'UNINITIALIZED':             def printl():                 if len(str(cls.b_len)) == 2:                     print(' ', end='')                 for x in range(cls.b_len):                     print(' '*6 + f'{cls.letters[x]}', end='')                 print('\n')              print('\n'*2)             printl()             for x in range(cls.b_len):                 print(f'{cls.b_len-x:0{len(str(cls.b_len))}}  {cls.board[x]}  {cls.b_len-x:0{len(str(cls.b_len))}}\n')             printl()             print('\n'*4)          else:             print('Unable to print board of uninitialized type')      @classmethod     def tile_convert(cls, x, display_tile=False):         if not display_tile:             if isinstance(x, str):                 return cls.letters.index(x)             else:                 return cls.letters[x]         else:  # display_tile converts the letter in {letter}{number} to a number             return cls.b_len - int(x)      @classmethod     def l_num_to_coord(cls, pos):         return Config.b_len - int(pos[1]), int(Config.tile_convert(pos[0]))      @classmethod     def coord_to_tile(cls, x, y):         return f'{Config.tile_convert(x)}{Config.tile_convert(y, True)}'      @classmethod     def c_convert(cls, color):         if color == 'White':             return 'b'         if color == "Black":             return 'w'  class ChessPiece:     def __init__(self, pos, color, num, piece):         self.x = int(Config.tile_convert(pos[0]))         self.y = Config.b_len - int(pos[1])         self.color = color         self.piece = piece         self.pieceid = num         self.moves = 0         self.captured = []         self.erased = False         self.set_id()         self.create()         Config.print_board()      def __str__(self):         return self.piece      def __repr__(self):         return self.pieceid      def set_id(self):         if self.__class__.__name__ != "Knight":             self.pieceid = f'{self.piece[0]}{self.pieceid}'         else:             self.pieceid = f'N{self.pieceid}'          if self.color is not None:             if self.color.lower() in ('black', 'white', 'b', 'w'):                 self.pieceid = self.color.lower()[0] + self.pieceid                 if self.color.lower() == 'b':                     self.color = 'Black'                 elif self.color.lower() == 'w':                     self.color = 'White'             else:                 self.color = None                 print("Invalid color input. Color not set.")                 self.set_id()         else:              self.pieceid = '_' + self.pieceid       def create(self):         if Config.board[self.y][self.x] != '___':             po = Config.board[self.y][self.x]             print(f'Piece {po} erased to make room for {self.pieceid}')          Config.board[self.y][self.x] = self.pieceid      def teleport(self, pos, record=False):         Config.board[self.y][self.x] = '___'          if record:             self.moves += 1             coord = Config.l_num_to_coord(pos)             if Config.board[coord[0]][coord[1]] != '___':                 self.captured.append(Config.board[coord[0]][coord[1]])                 print(f'{self.pieceid} has captured {Config.board[coord[0]][coord[1]]}!')          self.x = Config.tile_convert(pos[0])         self.y = Config.tile_convert(pos[1], True)          Config.board[self.y][self.x] = self.pieceid          Config.print_board()      def move(self, pos):         if pos in self.possible_moves():             coord = Config.l_num_to_coord(pos)             if Config.board[coord[0]][coord[1]] != '___':                 self.captured.append(Config.board[coord[0]][coord[1]])                 print(f'{self.pieceid} has captured {Config.board[coord[0]][coord[1]]}!')                 # Erase piece              if self.__class__ == Pawn:                 if abs(int(pos[1]) - Config.tile_convert(self.y, True)) == 2:                     self.two_move = True              self.teleport(pos)             self.moves += 1          else:             print(f'Unable to move to {pos}')       def get_info(self):         print(f'{self.__class__.__name__}:\n')         print('ID: ', self.pieceid)         print('Position: ', Config.tile_convert(self.x), Config.tile_convert(self.y, True), sep='')         print('Color: ', self.color)      def erase(self):  # Doesn't delete the piece. It can be brought back by moving it to a square         Config.board[self.y][self.x] = '___'         self.erased = True      def demo(self, rec=True):  # default board         for pos in self.demo_moves:             self.teleport(pos, rec)             sleep(Config.DEMTIME)          if self.__class__ == Pawn:             self.promote2(Queen)      @staticmethod     def castle(king, rook):         if not king.moves and not rook.moves:             if not king.in_check:                 pass   class Pawn(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8')         self.two_move = False      def possible_moves(self):         pos_moves = []          x, y = self.x, self.y          # Forward         if not self.moves: # Starting Position             if self.color != 'White':                 for new_y in (y+1, y+2):                     try:                         if Config.board[new_y][x] == '___':                             pos_moves.append(Config.coord_to_tile(x, new_y))                         else: break                     except IndexError: pass              if self.color != 'Black':                 for new_y in (y-1, y-2):                     try:                         if Config.board[new_y][x] == '___':                             pos_moves.append(Config.coord_to_tile(x, new_y))                         else: break                     except IndexError: pass          else:  # Post-Start             if self.color != 'White':                 try:                     if Config.board[y+1][x] == '___':                         pos_moves.append(Config.coord_to_tile(x, y+1))                 except IndexError: pass              if self.color != 'Black':                 try:                     if Config.board[y-1][x] == '___':                         pos_moves.append(Config.coord_to_tile(x, y-1))                 except IndexError: pass          # Capturing         if self.color != 'White':             if self.color is not None:                 try:                     if Config.c_convert(self.color) in Config.board[y+1][x+1]:                         pos_moves.append(Config.coord_to_tile(x+1, y+1))                 except IndexError: pass             else:                 try:                     if Config.board[y+1][x+1] != '___':                         pos_moves.append(Config.coord_to_tile(x+1, y+1))                 except IndexError: pass          if self.color != 'Black':             if self.color is not None:                 try:                     if Config.c_convert(self.color) in Config.board[y-1][x-1]:                         pos_moves.append(Config.coord_to_tile(x-1, y-1))                 except IndexError: pass             else:                 try:                     if Config.board[y+1][x+1] != '___':                         pos_moves.append(Config.coord_to_tile(x-1, y-1))                 except IndexError: pass          # En Passant           return sorted(pos_moves)      def promote(self, piece):  # oringal_piece = original_piece.promote(new_piece)         pos = f'{Config.tile_convert(self.x)}{Config.tile_convert(self.y, True)}'          return piece(pos, color=self.color, num='p')      def promote2(self, piece):         pos = f'{Config.tile_convert(self.x)}{Config.tile_convert(self.y, True)}'          self.__class__ = piece         self.__init__(pos, self.color, 'p')   class Knight(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('e1', 'f3', 'g5', 'h7', 'f8', 'e6', 'c5', 'd3', 'e1')      def possible_moves(self):         pos_moves = []         for x_off, y_off in ( (1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1) ):             new_x = self.x + x_off             new_y = self.y + y_off             if 0 <= new_x < Config.b_len and 0 <= new_y < Config.b_len:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, new_y))                 else:                     pos_moves.append(Config.coord_to_tile(new_x, new_y))          return sorted(pos_moves)   class Bishop(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('a1', 'e5', 'b8', 'h2', 'e5', 'a1')      def possible_moves(self):         pos_moves = []          x, y = self.x, self.y          right_up = zip(range(x + 1, Config.b_len), range(y - 1, -1, -1))         right_down = zip(range(x + 1, Config.b_len), range(y + 1, Config.b_len))          left_up = zip(range(x - 1, -1, -1), range(y - 1, -1, -1))         left_down = zip(range(x - 1, -1, -1), range(y + 1, Config.b_len))          for r in (right_up, right_down, left_up, left_down):             for new_x, new_y in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, new_y))                         if Config.board[new_y][new_x] != '___': break                     else: break                 else:                     pos_moves.append(Config.coord_to_tile(new_x, new_y))          return sorted(pos_moves)   class Rook(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('a1', 'a8', 'h8', 'h1', 'a1')      def possible_moves(self):         pos_moves = []          x, y = self.x, self.y          # Horizontal         for r in (range(x+1, Config.b_len), reversed(range(x))):             for new_x in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, y))                         if Config.board[y][new_x] != '___': break                     else: break                 else:                     pos_moves.append(Config.coord_to_tile(new_x, y))                     if Config.board[new_y][new_x] != '___': break          # Vertical         for r in (range(y+1, Config.b_len), reversed(range(y))):             for new_y in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][x]:                         pos_moves.append(Config.coord_to_tile(x, new_y))                         if Config.board[new_y][x] != '___': break                     else: break                 else:                     pos_moves.append(Config.coord_to_tile(x, new_y))                     if Config.board[new_y][new_x] != '___': break          return sorted(pos_moves)   class Queen(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('a1', 'h8', 'a8', 'h1', 'a1')      def possible_moves(self):         pos_moves = []          x, y = self.x, self.y          # Horizontal         for r in (range(x+1, Config.b_len), reversed(range(x))):             for new_x in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, y))                         if Config.board[y][new_x] != '___': break                     else: break                 else:                     pos_moves.append(f'{Config.tile_convert(new_x)}{Config.tile_convert(y, True)}')                     if Config.board[new_y][new_x] != '___': break          # Vertical         for r in (range(y+1, Config.b_len), reversed(range(y))):             for new_y in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][x]:                         pos_moves.append(Config.coord_to_tile(x, new_y))                         if Config.board[new_y][x] != '___': break                     else: break                 else:                     pos_moves.append(f'{Config.tile_convert(x)}{Config.tile_convert(new_y, True)}')                     if Config.board[new_y][new_x] != '___': break          #Diagonal         right_up = zip(range(x + 1, Config.b_len), range(y - 1, -1, -1))         right_down = zip(range(x + 1, Config.b_len), range(y + 1, Config.b_len))          left_up = zip(range(x - 1, -1, -1), range(y - 1, -1, -1))         left_down = zip(range(x - 1, -1, -1), range(y + 1, Config.b_len))          for r in (right_up, right_down, left_up, left_down):             for new_x, new_y in r:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, new_y))                         if Config.board[new_y][new_x] != '___': break                     else: break                 else:                     pos_moves.append(Config.coord_to_tile(new_x, new_y))          return sorted(pos_moves)   class King(ChessPiece):     def __init__(self, pos='a1', color=None, num='_'):         ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)         self.demo_moves = ('e4', 'd5', 'c4', 'c5', 'd6', 'e5', 'e4')         self.in_check = False      def possible_moves(self):         pos_moves = []          x, y = self.x, self.y          for x_off, y_off in ( (0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (-1, 1), (-1, -1), (1, -1) ):             new_x = self.x + x_off             new_y = self.y + y_off             if 0 <= new_x < Config.b_len and 0 <= new_y < Config.b_len:                 if self.color is not None:                     if self.color[0].lower() not in Config.board[new_y][new_x]:                         pos_moves.append(Config.coord_to_tile(new_x, new_y))                 else:                     pos_moves.append(Config.coord_to_tile(new_x, new_y))           return sorted(pos_moves)   # Some commands to start out with  Config.new_board('default')  r1 = Rook(color='w') n1 = Knight('a5', color='b') p1 = Pawn('e1', color='w') p2 = Pawn('e8', color='b') p3 = Pawn('f7', color='w') r1.teleport('b3') 

I plan to use the IDs in order to dictate piece images on the GUI.

Fresh Website for Dota Auto Chess

Why are you selling this site?
I'm a student in a poor life and need money :)

How is it monetized?
There is no Auto Chess website more than 3-4. Could be earn by adsense.

Does this site come with any social media accounts?
Instagram, twitter and facebook with 0 follower.

How much time does this site take to run?

What challenges are there with running this site?

Program for chess simulator

I have written an answer to this question on Stack Overflow. To make it easier for you, I have copy-pasted the main task below:

This is a so-called chess simulator, that will take a value and compare the numbers from both lists. If the numbers “threaten each other”, a point will be added. If both values are the same, it will not register the hit or miss and add an extra loop turn.

Here is my answer to this task:

import random svart = [18,28,38,58,68,78,88,47,46,45,44,43,42,41,37,26,15,57,66,75,84] #not entered the start positions as value (48) vit = [11,21,31,51,61,71,81,42,43,44,45,46,47,48,32,23,14,52,63,74,85] def schack(svart,vit):     hit = 0     miss = 0     for i in range(10000):         choice = random.choice(svart)         choice2 = random.choice(vit)         if choice == choice2:             i = i + 1          elif choice == svart[0] and choice2 == vit[0]:             hit += 1          elif choice == svart[1] and choice2 == vit[1]:             hit += 1          elif choice == svart[2] and choice2 == vit[2]:             hit += 1          elif choice == svart[3] and choice2 == vit[3]:             hit += 1          elif choice == svart[4] and choice2 == vit[4]:             hit += 1          elif choice == svart[5] and choice2 == vit[5]:             hit += 1          elif choice == svart[6] and choice2 == vit[6]:             hit += 1          elif choice == svart[7:14] and choice2 == vit[7:14]:             hit += 1          elif choice == svart[14] and choice2 == vit[2] or choice2 == vit[12] or choice2 == vit[14]:             hit += 1          elif choice == svart[15] and choice2 == vit[1] or choice2 == vit[15] or choice2 == vit[11]:             hit += 1          elif choice == svart[16] and choice2 == vit[0] or choice2 == vit[10] or choice2 == vit[16]:             hit += 1          elif choice == svart[17] and choice2 == vit[3] or choice2 == vit[17] or choice2 == vit[12]:             hit += 1          elif choice == svart[18] and choice2 == vit[11] or choice2 == vit[4] or choice2 == vit[18]:             hit += 1          elif choice == svart[19] and choice2 == vit[5] or choice2 == vit[10] or choice2 == vit[19]:             hit += 1          elif choice == svart[20] and choice2 == vit[6] or choice2 == vit[9] or choice2 == vit[20]:             hit += 1          elif choice == svart[2] or choice == svart[14] or choice == svart[12] and choice2 == vit[14]:             hit += 1          elif choice == svart[1] or choice == svart[11] or choice == svart[15] and choice2 == vit[15]:             hit += 1          elif choice == svart[0] or choice == svart[16] or choice == svart[10] and choice2 == vit[16]:             hit += 1          elif choice == svart[3] or choice == svart[12] or choice == svart[17] and choice2 == vit[17]:             hit += 1          elif choice == svart[4] or choice == svart[11] or choice == svart[18] and choice2 == vit[18]:             hit += 1          elif choice == svart[5] or choice == svart[10] or choice == svart[19] and choice2 == vit[19]:             hit += 1          elif choice == svart[20] or choice == svart[6] or choice == svart[9] and choice2 == vit[20]:             hit += 1           else:             miss += 1      print hit     print miss   schack(svart,vit) 

This would yield the (random) output:

8312 1551 

where there were 8312 hits, 1551 misses and (10000 - (8312 + 1551) =) 137 were not registered as choice and choice2 were the same.

So, I would like to know whether I could make this code shorter and more efficient (if possible).

Any help would be highly appreciated.

Inheritance vs Composition For Chess Pieces

A quick search of this stackexchange shows that in general composition is generally considered more flexible than inheritance but as always it depends on the project etc and there are times when inheritance is the better choice. I want to make a 3D chess game where each piece has a mesh, possibly different animations and so on. In this concrete example it seems like you could argue a case for both approaches am I wrong?

Inheritance would look something like this (with proper constructor etc)

class BasePiece {     virtual Squares GetValidMoveSquares() = 0;     Mesh* mesh;     // Other fields }  class Pawn : public BasePiece {    Squares GetValidMoveSquares() override; } 

which certainly obeys the “is-a” principle whereas composition would look something like this

class MovementComponent {     virtual Squares GetValidMoveSquares() = 0; }  class PawnMovementComponent {      Squares GetValidMoveSquares() override; }  enum class Type {      PAWN,      BISHOP, //etc }   class Piece {     MovementComponent* movementComponent;     MeshComponent* mesh;     Type type;     // Other fields  } 

Is it more a matter of personal preference or is one approach clearly a smarter choice than the other here?

What do I not understand about Alpha-Beta-Pruning in Chess?

I’m trying to write a chess engine, Min-Maxing works. Now I wanted to implement Alpha-Beta-Pruning, but despite reading about it and watching videos, I must have a severe misunderstanding somewhere.

  • For Min-Maxing, I build the complete search tree, and evaluate only the nodes at the deepest depth. Then go upwards, and “carry” the scores, without evaluating other nodes; I only compare the carried scores.

  • For ABP, I also build the complete search tree (?!), and evaluate only the nodes at the deepest depth. Then go upwards, and “carry” the scores; but this time I can often prune nodes, meaning that I don’t need to min-max that often, and also don’t have to evaluate all nodes at the deepest depth.

Thing is: I’m not limited by the times I have to evaluate nodes, I’m limited by memory (In size and access speed) because I still need to build a tree of millions of nodes, and prune it afterwards.

I assumed ABP should somehow occur earlier, so that I don’t even have to create branches, but that doesn’t work, since you have to always evaluate the deepest nodes for comparison (So you have to build the tree all the way).


I’m feeling like an idiot here, what do I miss?