Giter Site home page Giter Site logo

emychess's People

Contributors

blackstartx avatar bluwizard10 avatar emymin avatar zenithval avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

emychess's Issues

pawn queen swap broken.

when the queen is of the table and a pawn to the end of the board at opponent side, the pawn to queen swap broke. the opponent gets his color queen instead of mine. but the whole game also broke and no turns can be made any more.

EmyChess breaks when the users that are playing it leave the world

The chess board will be stuck in a "playing" state even though no one can move any pieces any no one is able to reset the game. Whoever is the master of the instance is shown as both of the current players that are playing, but they also cannot reset the board and don't see themselves as a player on the game.

Issue with castling

Hello, I enjoy the chessboard very much but small issue with the board logic. When castling would be illegal because a bishop line of sight would prevent castling, the board still let you castle.

If you plan future updates, here is a few suggestions:
1.Have a replay mode to rewatch the last played game.
2.An export feature where you can copy(clipboard) the notation of the game at the end of a match would be awesome.

Keep up the good work!

Nuka

ui proposal

hey there i changed a little bit the UI on my project, what do you think of it?

image

image

How do i make it work

I have downloaded the UdonSharp and Vrchat . but its not functional, should I reconfigure all of these?
image

Not Work?

I'm new to Udon side of things when it comes to VRChat so I could just be doing something wrong. I followed your directions for adding the prefab to my world, but when I go to test build none of the buttons seem to work and I can't start Chess match. I'm using the the VRChat Creator Companion; with everything up to date

This is how I fixed the castle bug, hope this helps! -Phrozen

Hello, I've been working on my own version of EmmyChess and I managed to fix the castle bug. My current version is very different from the asset so I will post some of the code to fix castle for the asset. If you want to see the changes I've made to emmy chess you can check out the Vrchat Map "Cozy Space". I had to basicly not call functions directly in order to avoid the crashing issue that came up a lot, so it caused me to update bools and call the bools instead of the direct function. I hope this helps, I am very new to coding, fixing this took probably a straight month of work.

//(added to defaultrules)
//Top part -

   [HideInInspector] 
   public bool BlackLeftCastle = true;
    [HideInInspector]
    public bool BlackRightCastle = true;
    [HideInInspector]
    public bool WhiteLeftCastle = true;
    [HideInInspector]
    public bool WhiteRightCastle = true; 
    [HideInInspector]
    public bool BlackMoveLeftCastle = true;
    [HideInInspector]
    public bool BlackMoveRightCastle = true;
    [HideInInspector]
    public bool WhiteMoveLeftCastle = true;
    [HideInInspector]
    public bool WhiteMoveRightCastle = true;
    [HideInInspector]
    public bool WhitePiecesRightCastle = false;
    [HideInInspector]
    public bool WhitePiecesLeftCastle = false;
    [HideInInspector]
    public bool BlackPiecesRightCastle = false;
    [HideInInspector]
    public bool BlackPiecesLeftCastle = false;      //I also added all these exactly the same to start() might not be important.
    [HideInInspector]
    [UdonSynced]
    public bool CastleInCheck = false;

//Added functions -

// (pseudolegalmoves)

else if (type == "king")
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
Piece squarepiece = board.GetGridPiece(x + i, y + j, grid);
if (squarepiece == null || (squarepiece != null && squarepiece.white != white))
{
index = AppendMove(index, x + i, y + j, legalMoves);
}
}
}
if (white)
{
if (WhiteRightCastle && WhiteMoveRightCastle && WhitePiecesRightCastle && !CastleInCheck)
{
index = AppendMove(index, x + 2, y, legalMoves);
}
if (WhiteLeftCastle && WhiteMoveLeftCastle && WhitePiecesLeftCastle && !CastleInCheck)
{
index = AppendMove(index, x - 2, y, legalMoves);
}
}
else
{
if (BlackRightCastle && BlackMoveRightCastle && BlackPiecesRightCastle && !CastleInCheck)
{
index = AppendMove(index, x + 2, y, legalMoves);
}
if (BlackLeftCastle && BlackMoveLeftCastle && BlackPiecesLeftCastle && !CastleInCheck)
{
index = AppendMove(index, x - 2, y, legalMoves);
}
}
}

//(iskingincheck)
if (opponentPseudoLegalMove == legalMovesEndMarker) { break; }
else
{
if (opponentPseudoLegalMove == threatenedPos)
{
isKingChecked = true;
CastleInCheck = true; //this is all thats added in order to not directly call iskingincheck
break;
}
}

//(new)

    public void CastleMoveCheck()
    {
        WhiteMoveRightCastle = true;
        BlackMoveRightCastle = true;
        WhiteMoveLeftCastle = true;
        BlackMoveLeftCastle = true;
        RequestSerialization();
    }
    public void CastleNotMoved(Piece movedPiece)
    {
        if (movedPiece.type == "king")
        {
            if (movedPiece.white)
            {
                WhiteMoveRightCastle = false;
                WhiteMoveLeftCastle = false;
            }
            else
            {
                BlackMoveRightCastle = false;
                BlackMoveLeftCastle = false;
            }
        }
        else if (movedPiece.type == "rook")
        {
            if (movedPiece.white)
            {
                if (movedPiece.x == 0 && movedPiece.y == 0) // Left rook initial position for white
                {
                    WhiteMoveLeftCastle = false;
                }
                else if (movedPiece.x == 7 && movedPiece.y == 0) // Right rook initial position for white
                {
                    WhiteMoveRightCastle = false;
                }
            }
            else
            {
                if (movedPiece.x == 0 && movedPiece.y == 7) // Left rook initial position for black
                {
                    BlackMoveLeftCastle = false;
                }
                else if (movedPiece.x == 7 && movedPiece.y == 7) // Right rook initial position for black
                {
                    BlackMoveRightCastle = false;
                }
            }
        }
        RequestSerialization();
    }

    public void CheckCastlePaths(Piece[] grid, Board board)
    {
         if (grid == null) { Debug.LogWarning("Empty grid, might be first turn"); return; }

        // Check White Right Castle
        WhitePiecesRightCastle = true;
        for (int i = 5; i < 7; i++) // Check squares between king and right rook for white
        {
            if (board.GetGridPiece(i, 0, grid) != null) // Assuming white's back rank is y = 0
            {
                WhitePiecesRightCastle = false;
                break;
            }
        }

        // Check White Left Castle
        WhitePiecesLeftCastle = true;
        for (int i = 1; i < 4; i++) // Check squares between king and left rook for white
        {
            if (board.GetGridPiece(i, 0, grid) != null) // Assuming white's back rank is y = 0
            {
                WhitePiecesLeftCastle = false;
                break;
            }
        }

        // Check Black Right Castle
        BlackPiecesRightCastle = true;
        for (int i = 5; i < 7; i++) // Check squares between king and right rook for black
        {
            if (board.GetGridPiece(i, 7, grid) != null) // Assuming black's back rank is y = 7
            {
                BlackPiecesRightCastle = false;
                break;
            }
        }

        // Check Black Left Castle
        BlackPiecesLeftCastle = true;
        for (int i = 1; i < 4; i++) // Check squares between king and left rook for black
        {
            if (board.GetGridPiece(i, 7, grid) != null) // Assuming black's back rank is y = 7
            {
                BlackPiecesLeftCastle = false;
                break;
            }
        }
        RequestSerialization();
    }
    public void CheckCastleSafety(Piece[] grid, Board board)
    {
        // Check squares next to the White King
        Vector2 whiteKingPos = board.whiteKing.GetVec();
        WhiteLeftCastle = !(IsSquareUnderAttack((int)whiteKingPos.x - 1, (int)whiteKingPos.y, false, grid, board) ||
                            IsSquareUnderAttack((int)whiteKingPos.x - 2, (int)whiteKingPos.y, false, grid, board));

        WhiteRightCastle = !(IsSquareUnderAttack((int)whiteKingPos.x + 1, (int)whiteKingPos.y, false, grid, board) ||
                             IsSquareUnderAttack((int)whiteKingPos.x + 2, (int)whiteKingPos.y, false, grid, board));

        // Check squares next to the Black King
        Vector2 blackKingPos = board.blackKing.GetVec();
        BlackLeftCastle = !(IsSquareUnderAttack((int)blackKingPos.x - 1, (int)blackKingPos.y, true, grid, board) ||
                            IsSquareUnderAttack((int)blackKingPos.x - 2, (int)blackKingPos.y, true, grid, board));

        BlackRightCastle = !(IsSquareUnderAttack((int)blackKingPos.x + 1, (int)blackKingPos.y, true, grid, board) ||
                             IsSquareUnderAttack((int)blackKingPos.x + 2, (int)blackKingPos.y, true, grid, board));
        RequestSerialization();
    }
    private bool IsSquareUnderAttack(int x, int y, bool byWhite, Piece[] grid, Board board)
    {
        foreach (Piece piece in board.GetAllPieces())
        {
            if (piece.white == byWhite)
            {
                Vector2[] pseudoLegalMoves = GetAllPseudoLegalMovesGrid(piece, grid, board.PawnThatDidADoublePushLastRound, 
              board);
                foreach (Vector2 move in pseudoLegalMoves)
                {
                    if (move == legalMovesEndMarker) break;
                    if (move.x == x && move.y == y)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

//(modified GetAlllegalMoves)

    public Vector2[] GetAllLegalMoves(Piece movedPiece, Board board)
    {
        Vector2[] pseudoLegalMoves = GetAllPseudoLegalMovesGrid(movedPiece, board.grid, board.PawnThatDidADoublePushLastRound, board);
        Vector2 piecePos = movedPiece.GetVec();
        Piece king = movedPiece.white ? board.whiteKing : board.blackKing;
        if (king != null)
        {
            Vector2 kingPos = king.GetVec();
            Piece[] currentGrid = board.grid;
            Piece[] testGrid = new Piece[currentGrid.Length];
            CastleInCheck = false;    // Reset CastleInCheck to false initially   <-----only line added.
            for (int i = 0; i < pseudoLegalMoves.Length; i++)
            {
                Vector2 pseudoLegalMove = pseudoLegalMoves[i];

                if (pseudoLegalMove == legalMovesEndMarker) { break; }
                else
                {
                    Array.Copy(currentGrid, testGrid, currentGrid.Length);

                    board.MoveGridPieceVec(piecePos, pseudoLegalMove, testGrid);
                    Piece PawnThatDidADoublePush = null;
                    if (movedPiece.type == "pawn" && (Mathf.Abs(movedPiece.x - (int)pseudoLegalMove.x) > 1))
                    {
                        PawnThatDidADoublePush = movedPiece;
                    }
                    Vector2 threatenedPos = movedPiece.type != "king" ? kingPos : pseudoLegalMove;
                    if (isKingInCheck(threatenedPos, testGrid, board, PawnThatDidADoublePush, movedPiece.white)) { pseudoLegalMoves[i] = legalMovesIgnoreMarker; }
                }
            }
        }
        return pseudoLegalMoves;
    }

//(modified Move)

    public int Move(Piece movedPiece, int x, int y, Board board)
    {
        int result = 0;
        if (anarchy)
        {
            Piece targetPiece = board.GetPiece(x, y);
            result = 1;
            if (targetPiece != null && targetPiece != movedPiece) { targetPiece._Capture(); result = 2; }
            movedPiece._SetPosition(x, y);
            return result;
        }
        else
        {
            Vector2[] legalMoves = GetAllLegalMoves(movedPiece, board);
            result = MoveLegalCheck(movedPiece, x, y, board, legalMoves);

            // Call CastleNotMoved whenever a piece is moved <---------
            if (result > 0)
            {
                CastleNotMoved(movedPiece);
            }

            return result;
        }
    }

//(modified MoveLegalCheck)

    public int MoveLegalCheck(Piece movedPiece, int x, int y, Board board, Vector2[] legalMoves)
    {
        int result = 0;
        Piece targetPiece = board.GetPiece(x, y);
        Vector2 move = new Vector2(x, y);
        bool legal = false;
        foreach (Vector2 legalMove in legalMoves)
        {
            if (legalMove != legalMovesIgnoreMarker)
            {
                if (legalMove == legalMovesEndMarker) break;
                if (move == legalMove) { legal = true; break; }
            }
        }
        if (legal)
        {
            if (targetPiece != null) { targetPiece._Capture(); result = 2; } else { result = 1; }

            if (movedPiece.type == "pawn" && movedPiece.x != x && board.GetPiece(x, y) == null) //EN PASSANT
            {
                board.PawnThatDidADoublePushLastRound._Capture();
                result = 2;
            }

            if (movedPiece.type == "king")
            {
                if (movedPiece.white)
                {
                    if (x - movedPiece.x == 2 && WhiteRightCastle && WhiteMoveRightCastle && WhitePiecesRightCastle && !CastleInCheck) // White right castle
                    {
                        Piece rookCastle = board.GetPiece(7, y);
                        rookCastle._SetPosition(x - 1, y);
                    }
                    else if (x - movedPiece.x == -2 && WhiteLeftCastle && WhiteMoveLeftCastle && WhitePiecesLeftCastle && !CastleInCheck) // White left castle
                    {
                        Piece rookCastle = board.GetPiece(0, y);
                        rookCastle._SetPosition(x + 1, y);
                    }
                }
                else
                {
                    if (x - movedPiece.x == 2 && BlackRightCastle && BlackMoveRightCastle && BlackPiecesRightCastle && !CastleInCheck) // Black right castle 
                    {
                        Piece rookCastle = board.GetPiece(7, y);
                        rookCastle._SetPosition(x - 1, y);
                    }
                    else if (x - movedPiece.x == -2 && BlackLeftCastle && BlackMoveLeftCastle && BlackPiecesLeftCastle && !CastleInCheck) // Black left castle
                    {
                        Piece rookCastle = board.GetPiece(0, y);
                        rookCastle._SetPosition(x + 1, y);
                    }
                }
            }

            if (movedPiece.type == "pawn" && Mathf.Abs(y - movedPiece.y) == 2)
            {
                board.PawnThatDidADoublePushLastRound = movedPiece;
            }
            else
            {
                board.PawnThatDidADoublePushLastRound = null;
            }
            CastleNotMoved(movedPiece);
            movedPiece.hasMoved = true;
            movedPiece._SetPosition(x, y);

            return result;
        }
        else
        {
            movedPiece._SetPosition(movedPiece.x, movedPiece.y);
            return 0;
        }
    }

//(Board.cs Changes - Removed the castle move from board.cs)

    public void MoveGridPiece(int ox, int oy, int tx, int ty, Piece[] grid)
    {
        Piece piece = GetGridPiece(ox, oy, grid);
        // No en passant or castling logic
        SetGridPiece(tx, ty, piece, grid);
        SetGridPiece(ox, oy, null, grid);
    }


    /// <summary>
    /// Simulate a piece's move on a grid, including capture, en passant and castling
    /// </summary>
    /// <param name="original">Starting position</param>
    /// <param name="target">Target position</param>
    /// <param name="grid"></param>
    public void MoveGridPieceVec(Vector2 original, Vector2 target, Piece[] grid)
    {
        MoveGridPiece((int)original.x, (int)original.y, (int)target.x, (int)target.y, grid);
    }

//(Chessmanger Changes)

//(Endturn)
board.currentRules.CheckCastlePaths(board.grid, board); // Check castle paths at end turn <-added
board.currentRules.CheckCastleSafety(board.grid, board); // Check castle safety at end turn<-added
_RefreshUI();
RequestSerialization();

//(startgame)
board.currentRules.CheckCastlePaths(board.grid, board); // Check castle paths at game start
board.currentRules.CheckCastleSafety(board.grid, board); // Check castle safety at game start

//(endgame)
board.currentRules.CastleMoveCheck();

A Tiny Issue

Hello again. I noticed a little issue with your Chess Clock... everything works great! but.... you have the Chess clock set wrong. I looked up the official time rules to be sure of this. When a Chess match starts Black side starts the clock for White... your board is set to where White starts the clock for black, that's not the correct way to start a match.

Is there a way I can correct the clock in the scene? I tried on my own but couldn't seem to tweak the clock setup.

Broken with the new VCC

As soon as I try to import emychess into a VCC (vrchat creator companion) project, Unity immediately pops up its crash window and proceeds to crash the project. If I then open the project back up, A prefab message saying something about unpacking will persist and not go away unless I remove emychess from the files and then re-launch the project. I know this hasnt been updated since back in 2021 but it's one of the higher quality free chess boards that I love using. If you could fix it/update it that would be amazing~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.