# AsymmetricRandom Chess

import random

from pychess.Utils.const import VARIANTS_SHUFFLE, ASYMMETRICRANDOMCHESS
from pychess.Utils.Board import Board


class AsymmetricRandomBoard(Board):
    variant = ASYMMETRICRANDOMCHESS
    __desc__ = _(
        "FICS wild/4: http://www.freechess.org/Help/HelpFiles/wild.html\n"
        + "* Randomly chosen pieces (two queens or three rooks possible)\n"
        + "* Exactly one king of each color\n"
        + "* Pieces placed randomly behind the pawns, SUBJECT TO THE CONSTRAINT THAT THE BISHOPS ARE BALANCED\n"
        + "* No castling\n"
        + "* Black's arrangement DOES NOT mirrors white's"
    )
    name = _("Asymmetric Random")
    cecp_name = "wild/4"
    need_initial_board = True
    standard_rules = True
    variant_group = VARIANTS_SHUFFLE

    def __init__(self, setup=False, lboard=None):
        if setup is True:
            Board.__init__(self, setup=self.asymmetricrandom_start(), lboard=lboard)
        else:
            Board.__init__(self, setup=setup, lboard=lboard)

    def asymmetricrandom_start(self):
        white = random.sample(("r", "n", "b", "q") * 16, 7)
        white.append("k")
        black = white[:]
        random.shuffle(white)
        random.shuffle(black)

        # balance the bishops (put them on equal numbers of dark and light squares)
        whitedarkbishops = 0
        whitelightbishops = 0
        for index, piece in enumerate(white):
            if piece == "b":
                if index % 2 == 0:  # even numbered square on the A rank are dark
                    whitedarkbishops += 1
                else:
                    whitelightbishops += 1
        blackdarkbishops = 0
        blacklightbishops = 0
        blackbishoprandomindexstack = []
        for index, piece in enumerate(black):
            if piece == "b":
                if index % 2 == 1:  # odd numbered squares on the H rank are dark
                    blackdarkbishops += 1
                else:
                    blacklightbishops += 1
                blackbishoprandomindexstack.append(index)
        random.shuffle(blackbishoprandomindexstack)

        class RandomEnumeratePieces:
            def __init__(self, pieces):
                self.pieces = pieces[:]
                self.randomindexstack = list(range(8))
                random.shuffle(self.randomindexstack)

            def __iter__(self):
                return self

            def __next__(self):
                if not self.randomindexstack:
                    raise StopIteration
                else:
                    randomindex = self.randomindexstack.pop()
                    return randomindex, self.pieces[randomindex]

        while (whitedarkbishops != blackdarkbishops) or (
            whitelightbishops != blacklightbishops
        ):
            bishopindex = blackbishoprandomindexstack.pop()
            for index, piece in RandomEnumeratePieces(black):
                if piece != "b":
                    if (
                        (blackdarkbishops > whitedarkbishops)
                        and (bishopindex % 2 == 1)
                        and (index % 2 == 0)
                    ):
                        black[bishopindex] = piece
                        black[index] = "b"
                        blacklightbishops += 1
                        blackdarkbishops = (
                            blackdarkbishops > 0 and (blackdarkbishops - 1) or 0
                        )
                        break
                    elif (
                        (blacklightbishops > whitelightbishops)
                        and (bishopindex % 2 == 0)
                        and (index % 2 == 1)
                    ):
                        black[bishopindex] = piece
                        black[index] = "b"
                        blackdarkbishops += 1
                        blacklightbishops = (
                            blacklightbishops > 0 and (blacklightbishops - 1) or 0
                        )
                        break

        tmp = (
            "".join(black)
            + "/pppppppp/8/8/8/8/PPPPPPPP/"
            + "".join(white).upper()
            + " w - - 0 1"
        )

        return tmp


if __name__ == "__main__":
    Board = AsymmetricRandomBoard(True)
    for i in range(10):
        print(Board.asymmetricrandom_start())
