অ্যান্টেসিস খেলুন!


19

https://en.wikipedia.org/wiki/Losing_chess

এটি মূলত দাবা টুর্নামেন্ট , তবে অ্যান্টিথেসের জন্য;)

উদ্ভাবিত অনেক দাবা রূপগুলির মধ্যে একটি অ্যান্টিচেস । লক্ষ্যটি হ'ল আপনার সমস্ত টুকরা হারাতে (এটি কিছুটা অদ্ভুত বলে মনে হতে পারে তবে এটি একটি কারণে অ্যান্টিথেস বলে)।

নিয়ম

অ্যান্টিচেসের নিয়মগুলি স্ট্যান্ডার্ড দাবা'র সাথে খুব মিল - তবে কয়েকটি মোটামুটি ছোটখাটো পার্থক্য রয়েছে। আমি উপরে উল্লিখিত লক্ষ্যটি হ'ল আপনার সমস্ত টুকরোগুলি হারাতে। এটি ঘটানোর জন্য, যদি আপনার প্রতিপক্ষের কাছে আপনার কোনও একটি টুকরো ক্যাপচার করার সুযোগ থাকে, তবে তিনিই এই পদক্ষেপ নিতে পারেন। আপনি যদি তাকে এক পালনে একাধিক সম্ভাবনা দেন তবে অন্য খেলোয়াড় তার পালা বেছে নিতে পারে। আরেকটি বিষয় যা পরিবর্তিত হয়েছে তা হ'ল রাজার কোনও বিশেষ ক্ষমতা নেই - যেমন আপনি নিজের প্রতিপক্ষকে থামাতে পারবেন না, এবং আপনি তাকে জোর করে পরীক্ষা করতে পারবেন না।

মানক গেমের নিম্নলিখিত পরিবর্তনগুলিও প্রযোজ্য (তারা গেমটি সহজতর করতে সহায়তা করে):

  • এন পাসেন্ট উপেক্ষা করা হবে।
  • কাস্টিং সম্ভব নয়।
  • পঞ্চাশ-পদক্ষেপ নিয়ম স্বয়ংক্রিয়ভাবে (ক ড্র খেলা প্রান্ত অর্থ) প্রযোজ্য।
  • পন্ডিতরা তারা কী প্রচার করে তা চয়ন করতে সক্ষম হবে।
  • যদি কোনও খেলোয়াড়ের চলতে 2 সেকেন্ডের বেশি সময় প্রয়োজন হয় তবে সে খেলাটি হারাবে।
  • একটি অবৈধ পদক্ষেপ ফিরিয়ে দেওয়ার ফলে গেমটি হারাতে হবে।
  • জয়ের জন্য, আপনার বিরোধীদের অবশ্যই আপনার সমস্ত টুকরো ক্যাপচার করতে হবে
  • হোয়াইট খেলা শুরু।
  • সাদা ক্ষেত্রের "নীচে" (y = 0) স্থাপন করা হয়েছে, কালো শীর্ষে অবস্থিত (y = 7)।
  • আপনার বট (ইন্টারনেট, ফাইল, অন্যান্য বট, ...) ব্যতীত অন্য সংস্থানগুলিতে অ্যাক্সেস নিষিদ্ধ।

স্কোরিং

  • বিজয়ী আপনাকে 3 পয়েন্ট, একটি অঙ্কন 1 পয়েন্ট এবং 0 পয়েন্ট হারাবে।
  • প্রতিটি জমা 10 বার (সাদা হিসাবে 5 বার, কালো হিসাবে 5) একে অপরের জমা দেওয়ার বিরুদ্ধে খেলবে।

আপনার বট লেখা

কন্ট্রোলার কোডটি এখানে রয়েছে: https://github.com/JJ-Atkinson/SimpleAntichessKOTH

আপনি জাভা বা গ্রোভির যে কোনও একটিতে আপনার বট লিখতে পারেন। বট লিখতে আপনাকে অবশ্যই Playerক্লাসটি প্রসারিত করতে হবে । খেলোয়াড় শ্রেণীর একটি বিমূর্ত পদ্ধতি রয়েছে Move getMove(Board board, Player enemy, Set<Move> validMoves)

দরকারী পদ্ধতিগুলির জন্য এখানে দ্রুত পাল্টে দেওয়া:

Player:

  • List<Piece> getPieces(Board board): বোর্ডে থাকা আপনার সমস্ত টুকরো ফিরিয়ে দিন।
  • PieceUpgradeType pieceUpgradeType: যদি / যখন আপনার কোনও পদ্ম বোর্ডের শেষ প্রান্তে পৌঁছে যায়, আপনি আপগ্রেড করতে চান এমন টুকরোটির সাথে এটি নির্ধারণ করতে হবে। আপনি এর উপায় নেই ROOK, KNIGHT, QUEEN, BISHOP, এবং KING

Board:

  • Field getFieldAtLoc(Location loc): Fieldলোকেশন এ ফিরে । এটির একটি মিলে যাওয়ার getAtপদ্ধতি রয়েছে যাতে আপনি গ্রোভি ব্যবহার করে লিখতে পারেন board[loc]
  • Field getFieldAtLoc(int x, int y): Fieldলোকেশন এ ফিরে । এটির একটি মিলে যাওয়ার getAtপদ্ধতি রয়েছে যাতে আপনি গ্রোভি ব্যবহার করে লিখতে পারেন board[x, y]
  • Board movePiece(Player player, Move move): বোর্ডে সরানো যাতে আপনি দেখতে পান যে এটি কীভাবে কার্যকর হবে। এটি নতুন বোর্ড ফেরত দেয়।

যদি আপনি আপনার বিরোধীদের টুকরো দেখতে চান তবে কেবল লিখুন enemy.getPieces(board)। আপনার বটটি লাইনআপে যুক্ত করতে নিম্নলিখিত লাইনটি যুক্ত করুন PlayerFactory:

put(YourBot.class, { new YourBot() } )

আপনার বটটি ডিবাগ করছে:

আমি আপনার বটগুলি ডিবাগ করতে সহায়তা করার জন্য বেশ কয়েকটি সরঞ্জাম অন্তর্ভুক্ত করেছি। আপনার গেমটি সরাসরি চালিত হয়েছে তা দেখতে আপনি Game#DEBUGপতাকাটিকে সত্যে সেট করতে পারেন । আপনি এই জাতীয় একটি আউটপুট পাবেন:

Game started. Players: [OnePlayBot(WHITE), SacrificeBot(BLACK)]
...
BLACKs turn.
validMoves: [Move(Piece(BLACK, PAWN, Loc(0, 6)), Loc(0, 5)), ...]
board:
RKBQIBKR
PPPPPPPP
--------
--------
--------
p-------
-ppppppp
rkbqibkr

captureless turns: 1
chosen move: Move(Piece(BLACK, PAWN, Loc(7, 6)), Loc(7, 4))
Game over? false

==============================

WHITEs turn.
validMoves: [Move(Piece(WHITE, ROOK, Loc(0, 0)), Loc(0, 1)), ...]
board:
RKBQIBKR
PPPPPPP-
--------
-------P
--------
p-------
-ppppppp
rkbqibkr

...

(হোয়াইট আপার কেস, বাদশাকে দেখানো হয়েছে i)

যদি আপনার কনসোল utf-8 বিশেষ অক্ষর সমর্থন করে, আপনি এমনকি দাবা চরগুলি দিয়ে বোর্ডটি প্রদর্শন করে এটি ব্যবহার করতে পারেন Board#USE_UTF8_TO_STRING:

♜♞♝♛♚♝—♜
♟—♟♟♟♟♟♟
————————
—♟——————
————————
♙———————
—♙♙♙♙♔♙♙
♖♘♗♕—♗♘♖

(এটি একটি মনো স্পেসযুক্ত ফন্টের সাথে আরও ভাল দেখাচ্ছে)

অযাচিত আউটপুটটির বন্যা রোধ Main#mainকরতে আপনার এই ফাংশনটি এমন কিছুতে পরিবর্তন করা উচিত :

new Game(new MyBot(), new SacrificeBot()).run()

আপনার বটটি সাদা হিসাবে খেলতে বাম দিকে রাখুন, কালো হিসাবে খেলতে ডানদিকে রাখুন।

নিয়ামক নির্মাণ:

কন্ট্রোলারটি গ্রোভিতে লেখা হয়, সুতরাং আপনার অবশ্যই জাভা এবং গ্রোভি ইনস্টল করা উচিত। আপনি গ্রোভি ইনস্টল করতে না চাইলে আপনি গ্রেডল বিল্ড ফাইলটি ব্যবহার করতে পারেন যা নিয়ামকের সাথে আসে (এটি পরীক্ষা করা হয়নি)। আপনি যদি গ্রোভি বা গ্রেড ব্যবহার করতে না চান তবে আপনি সর্বশেষ প্রকাশের জারটি ব্যবহার করতে পারেন ( https://github.com/JJ-Atkinson/SimpleAntichessKOTH/relayss )। আপনি যদি এটি করেন তবে আপনার নিজের mainপদ্ধতি তৈরি করতে হবে এবং খেলোয়াড় কারখানায় ম্যানুয়ালি আপনার বট যুক্ত করতে হবে। উদাহরণ:

PlayerFactory.players.put(YourBot.class, { new YourBot() } )
new Runner().runGames();

(নোট করুন যে আপনি এখনও ডিবাগ পতাকা এবং স্টাফ সেট করতে পারেন)

যে কোনও এবং সমস্ত বাগ সন্ধান প্রশংসা করা হয়!

স্কোর:

SearchBot -> 101
SacrificeBot -> 81
MeasureBot -> 37
RandomBot -> 28
OnePlayBot -> 24

দয়া করে মনে রাখবেন যে আমি সর্বদা নতুন জমা দিতে ইচ্ছুক!


আপনি যদি গ্রোভি এবং ইন্টেলিজি পছন্দ করেন ... আপনার কোটলিন
TheNumberOne

আমি এর আগে কোটলিনকে দেখেছি, তবে কখনও এটিকে ভালো করে দেখিনি। এটিকে কিন্ডার / গ্রোভি ম্যাশআপের মতো দেখায় (তবে ঠিক আছে - গ্রোভি এবং স্কেলা আমার প্রিয় ভাষা;)
জে আতকিন

আমি এর আগে কখনও স্কাল ব্যবহার করিনি ... তবে জাভা থেকে গুভি কোড কল করার চেয়ে জাভা থেকে কোটলিন কোড কল করা অনেক সহজ।
One

1
আপনি কি রাজাতে আপগ্রেড করতে পারবেন?!? অবশ্যই নয় ...
wizzwizz4

1
@ wizzwizz4 অ্যান্টিচেসে, আপনি পারেন।
প্রোগ্রামফক্স

উত্তর:


6

SearchBot

এখন পর্যন্ত সবচেয়ে ধীরে বট, তবে এখনও চলন্তে 2 সেকেন্ডের চেয়ে দ্রুত এবং এটি বর্তমানে পোস্ট করা সমস্ত বটকে পরাজিত করে। এটি বৈধ পদক্ষেপের পরে কোনওটি ঘটে এবং সেই পদক্ষেপগুলির পরে কোনও পদক্ষেপের পরে কী ঘটতে পারে তা দেখে এবং সর্বোত্তম ফলাফল কী হবে তা স্থির করে। দুর্ভাগ্যক্রমে এটি গভীরতর অনুসন্ধান করতে পারে না কারণ এরপরে এটি 2 সেকেন্ডের বেশি সময় নেয়।

package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Color
import com.ppcgse.koth.antichess.controller.Location
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import groovy.lang.Tuple

/**
 * Created by ProgramFOX on 12/22/15.
 */

 class SearchBot extends Player {
    {pieceUpgradeType = PieceUpgradeType.KING}

    @Override
    Move getMove(Board board, Player opponent, Set<Move> validMoves) {
        return getMoveInternal(board, this, opponent, validMoves, 2)[0]
    }

    Tuple getMoveInternal(Board board, Player whoseTurn, Player opponent, Set<Move> validMoves, Integer depth) {
        def bestScore = null
        def currentlyChosenMove = null
        validMoves.each { m ->
            def opponentPiecesValueBefore = opponent.getPieces(board).sum { getPieceValue(it.getType()) }
            def newBoard = board.movePiece(whoseTurn, m)
            def opponentPiecesValueAfter = opponent.getPieces(newBoard).sum { getPieceValue(it.getType()) }
            if (opponentPiecesValueAfter == null) {
                opponentPiecesValueAfter = 0
            }
            def score = opponentPiecesValueAfter - opponentPiecesValueBefore
            if (whoseTurn.getTeam() == Color.BLACK) {
                score = -score
            }
            if (depth > 1) {
                def validMovesNow = genValidMoves(opponent, whoseTurn, newBoard)
                def goDeeper = true
                if (validMovesNow == null || validMovesNow.size() == 0) {
                    def toAdd = -999
                    if (whoseTurn.getTeam() == Color.BLACK) {
                        toAdd = -toAdd
                    }
                    score += toAdd
                    goDeeper = false
                }
                if (goDeeper) {
                    score += getMoveInternal(newBoard, opponent, whoseTurn, validMovesNow, depth - 1)[1]
                }
            }
            if (bestScore == null) {
                bestScore = score
                currentlyChosenMove = m
            }
            if ((whoseTurn.getTeam() == Color.WHITE && score > bestScore) || (whoseTurn.getTeam() == Color.BLACK && score < bestScore))  {
                bestScore = score
                currentlyChosenMove = m
            }
        }
        return new Tuple(currentlyChosenMove, bestScore)
    }

    Double getPieceValue(PieceType pieceType) {
        switch (pieceType) {
            case PieceType.KING:
                return 1
            case PieceType.PAWN:
                return 1.5
            case PieceType.KNIGHT:
                return 2.5
            case PieceType.BISHOP:
                return 3
            case PieceType.ROOK:
                return 5
            case PieceType.QUEEN:
                return 9
            default:
                return 0
        }
    }

    // Copied from Game.groovy and a bit modified.
    // I actually need this.
    Set<Move> genValidMoves(Player player, Player enemy, Board board) {
        def allMoves = player.getPieces(board).collect { [it, it.getValidDestinationSet(board)] }
        def attackMoves = allMoves
                .collect { pair ->
            def piece = pair[0]
            def dests = pair[1]
            [piece, dests.findAll { board.getFieldAtLoc(it as Location)?.piece?.team == enemy.team }]
        }.findAll { it[1] }

        if (attackMoves.isEmpty())
            return allMoves.collect {
                Piece piece = it[0] as Piece
                return it[1].collect { loc -> new Move(piece, loc as Location) }
            }.flatten() as Set<Move>
        else
            return attackMoves.collect {
                Piece piece = it[0] as Piece
                return it[1].collect { loc -> new Move(piece, loc as Location) }
            }.flatten() as Set<Move>
    }
 }

4

SacrificeBot

এই বটটি অন্য খেলোয়াড়ের সমস্ত চালচলন যাচাই করবে এবং তাদের মধ্যে কোনও ছেদ করা হয়েছে কিনা তা পরীক্ষা করবে (যেমন টুকরাটি মারা যাবে)। (এটি আমার প্রত্যাশার চেয়ে অনেক বেশি ভাল কাজ করেছে;)

package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Color
import com.ppcgse.koth.antichess.controller.Location
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import java.util.concurrent.ThreadLocalRandom

/**
 * Created by Jarrett on 12/19/15.
 */
class SacrificeBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    Move getMove(Board board, Player enemy, Set<Move> validMoves) {
        def enemyPieces = enemy.getPieces(board)
        def pawnMoves = getPawnsMoves(board, enemyPieces)
        def enemyPlayerValidMoves = (enemyPieces
                                        .collect { it.getValidDestinationSet(realBoard) }
                                        .flatten() as List<Location>)
        enemyPlayerValidMoves += pawnMoves

        def sacrificeMove = validMoves
                                .find {enemyPlayerValidMoves.contains(it.destination)}

        if (sacrificeMove)
            return sacrificeMove
        else
            return randomMove(validMoves)
    }

    def randomMove(Set<Move> validMoves) {
        return validMoves[ThreadLocalRandom.current().nextInt(validMoves.size())];
    }

    def getPawnsMoves(Board board, List<Piece> allPieces) {
        def direction = getTeam() == Color.BLACK ? 1 : -1;
        def pawns = allPieces.findAll {it.type == PieceType.PAWN}
        def pawnAttacks = (pawns.collect {
                                    [it.loc.plus(-1, direction), it.loc.plus(1, direction)]
                                }.flatten()
                                ).findAll {
                                    ((Location) it).isValid()
                                }
        return pawnAttacks as List<Location>
    }
}

3

OnePlayBot

একটি মাত্র প্লে সহ ডেড সরল বট। এটি একটি রোককে আপগ্রেড করবে।

package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player
import com.ppcgse.koth.antichess.controller.ReadOnlyBoard

public class OnePlayBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    public Move getMove(ReadOnlyBoard board, Player enemy, Set<Move> moves) {
        return new ArrayList<Move>(moves).get(0);
    }

}

3

RandomBot

এটি হ'ল আদেশ র্যান্ডম বট। এটি সর্বদা একটি দৃশ্যে আপগ্রেড হবে।

package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.ReadOnlyBoard

import java.util.concurrent.ThreadLocalRandom;

public class TestBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    public Move getMove(ReadOnlyBoard board, Player enemy, Set<Move> moves) {
        return moves[ThreadLocalRandom.current().nextInt(moves.size())];
    }

}

3

MeasureBot

এই যে বটটি আমি দিয়ে শুরু করেছি; আমি এটি প্রসারণে কাজ করছি কিন্তু তারপরে আমি গভীর ক্লোন বাগটি পেরিয়ে এসেছিলাম এবং তারপরে আমি ভাবলাম "ভাল, আসুন এই বটটি ইতিমধ্যে জমা দিন, এটি র্যান্ডমবট এবং ওয়ানপ্লেবটের চেয়ে আরও ভাল পারফর্মেন্স করে, এবং আমি পরে সর্বদা একটি নতুন বট জমা দিতে পারি" , সুতরাং এটি এখানে:

package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import java.util.concurrent.ThreadLocalRandom

/**
 * Created by ProgramFOX on 12/21/15.
 */

 class MeasureBot extends Player {
    {pieceUpgradeType = PieceUpgradeType.KING}

    @Override
    Move getMove(Board board, Player opponent, Set<Move> validMoves) {
        def opponentPieces = opponent.getPieces(board)
        def mustCapture = opponentPieces.find { it.loc == validMoves[0].destination } != null
        def chosen = null
        if (mustCapture) {
            def piecesThatCanBeTaken = opponentPieces.findAll { validMoves.collect { it.getDestination() }.contains(it.loc) }
            def lowestAmount = getPieceValue(piecesThatCanBeTaken.sort { getPieceValue(it.getType()) }[0].getType())
            def piecesWithLowestValue = piecesThatCanBeTaken.findAll { getPieceValue(it.getType()) == lowestAmount }
            def chosenOnes = validMoves.findAll { m -> piecesWithLowestValue.find { it.loc ==  m.destination } != null }
            chosen = chosenOnes.sort { getPieceValue(it.piece.getType()) }.reverse()[0]
        } else {
            chosen = randomMove(validMoves);
        }
        return chosen
    }

    Double getPieceValue(PieceType pieceType) {
        switch (pieceType) {
            case PieceType.KING:
                return 1
            case PieceType.PAWN:
                return 1.5
            case PieceType.KNIGHT:
                return 2.5
            case PieceType.BISHOP:
                return 3
            case PieceType.ROOK:
                return 5
            case PieceType.QUEEN:
                return 9
            default:
                return 0
        }
    }

    def randomMove(Set<Move> validMoves) {
        return validMoves[ThreadLocalRandom.current().nextInt(validMoves.size())];
    }
 }

মেজারবট দেখায় এটির কোনও কিছু ক্যাপচার করার দরকার আছে: এটি যদি তা না করে তবে এটি কেবল একটি এলোমেলো পদক্ষেপ করে। যদি এটি হয়, তবে সিদ্ধান্ত নেবে কোন টুকরোটি নেবে: এটি নিম্ন পিস মান সহ একটি বেছে নেবে কারণ সেগুলি তার নিজস্ব টুকরো কম ক্যাপচার করতে পারে। এবং যদি সর্বনিম্ন সম্ভাব্য মান সহ কোনও টুকরোটি নেওয়ার একাধিক উপায় থাকে তবে এটি এটি সর্বোচ্চ সম্ভাব্য মান সহ টুকরো দিয়ে ক্যাপচার করবে: এটি যদি এটি করে, তবে এটি ক্যাপচারিং টুকরোটিকে অন্য টুকরো নিকটে আনবে (প্রথমদিকে) গেমটি, কমপক্ষে) এবং আপনি বরং নিম্ন-মানের একটির চেয়ে একটি উচ্চ-মূল্যবান টুকরা হারাতে চান।

এটি আমি ব্যবহৃত টুকরা মানগুলির একটি তালিকা:

  • রাজা: ঘ
  • বন্ধ
  • নাইট: 2.5
  • বিশপ: 3
  • রুক: 5
  • রানী: 9

যখন কোনও মহিমা প্রচার করে, এটি সর্বদা একজন কিংকে প্রচার করবে কারণ এটি সর্বনিম্ন-মূল্যবান টুকরা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.