Beispiel #1
0
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY)
        {
            int smallestSize = BoardState.Height * BoardState.Width + 1;

            resultBitmap = null;
            resultX      = 0;
            resultY      = 0;

            //TODO: If we weren't a singleton we could track our used Width/Height
            int currentHeight = CalcUsedHeight(ref board);
            int currentWidth  = CalcUsedWidth(ref board);

            //Console.WriteLine($"Current {currentWidth}x{currentHeight}");

            for (var x = 0; x < BoardState.Width; x++)
            {
                for (var y = 0; y < BoardState.Height; y++)
                {
                    foreach (var bitmap in piece.PossibleOrientations)
                    {
                        var size = Math.Max(currentWidth, x + bitmap.Width) * Math.Max(currentHeight, y + bitmap.Height);

                        if (size < smallestSize && x + bitmap.Width <= BoardState.Width && y + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, x, y))
                        {
                            smallestSize = size;
                            resultBitmap = bitmap;
                            resultX      = x;
                            resultY      = y;
                        }
                    }
                }
            }

            return(resultBitmap != null);
        }
Beispiel #2
0
 // to spawn a new object dropping out of the box by gravity
 public void spawnNew(PieceDefinition pd, Vector3 pos, float dropSpeed, int skinNum)
 {
     isActive = true;
     piece    = new GamePiece(pd, this, skinNum, position - pos);
     piece.init();
     applyTweening(dropSpeed);
 }
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int x, out int y)
        {
            for (var oppositeWallGap = 0; oppositeWallGap < BoardState.Width; oppositeWallGap++)
            {
                //TODO: Could use the minimum of the size of the sides of the bitmap in this gap < part to skip some wasteful loops
                for (var gap = 0; gap < BoardState.Height; gap++)
                {
                    foreach (var bitmap in piece.PossibleOrientations)
                    {
                        //Try place in x direction
                        if (gap + bitmap.Width <= BoardState.Width && oppositeWallGap + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, gap, oppositeWallGap))
                        {
                            resultBitmap = bitmap;
                            x            = gap;
                            y            = oppositeWallGap;
                            return(true);
                        }

                        //Try place in y direction
                        if (oppositeWallGap + bitmap.Width <= BoardState.Width && gap + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, oppositeWallGap, gap))
                        {
                            resultBitmap = bitmap;
                            x            = oppositeWallGap;
                            y            = gap;
                            return(true);
                        }
                    }
                }
            }

            resultBitmap = null;
            x            = -1;
            y            = -1;
            return(false);
        }
Beispiel #4
0
 public GamePiece(PieceDefinition newPd, Board newMaster, int type, Vector3 newPosition)
 {
     pd = newPd;
     //Debug.Log(pd);
     master   = newMaster;
     slotNum  = type;
     position = newPosition;
 }
Beispiel #5
0
        public void PlayerPlacedPiece(int player, PieceDefinition piece, int x, int y, PieceBitmap bitmap)
        {
            Console.WriteLine($"Player {player} placed {piece.Name} at {x},{y}");

            if (PrintBoardsAfterPlacement)
            {
                PrintBoards(true);
            }
        }
Beispiel #6
0
 // converts a piece that is here to be a special piece
 public void convertToSpecial(PieceDefinition pd)
 {
     if (isFilled)
     {
         piece.pd.performPower(arrayRef); // trigger specials if any
     }
     piece.destroy(0);
     piece.specialMe(pd);
 }
Beispiel #7
0
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY)
        {
            resultBitmap = null;
            resultX      = -1;
            resultY      = -1;

            //TODO: We could do better with a good tiebreaker
            int bestScore       = int.MaxValue;
            int tieBreakerScore = int.MaxValue;
            int tiedForBest     = 0;

            foreach (var bitmap in piece.PossibleOrientations)
            {
                for (int x = 0; x < BoardState.Width - bitmap.Width + 1; x++)
                {
                    for (int y = 0; y < BoardState.Height - bitmap.Height + 1; y++)
                    {
                        if (board.CanPlace(bitmap, x, y))
                        {
                            CalculateScore(board, bitmap, x, y, _doubler, out var score);
                            if (score < bestScore)
                            {
                                bestScore       = score;
                                tieBreakerScore = x + y;

                                resultBitmap = bitmap;
                                resultX      = x;
                                resultY      = y;
                                tiedForBest  = 0;
                            }
                            else if (score == bestScore)
                            {
                                tiedForBest++;

                                int ourTieBreaker = x + y;

                                if (ourTieBreaker < tieBreakerScore)
                                {
                                    //Console.WriteLine("Beat the tie");
                                    tieBreakerScore = ourTieBreaker;

                                    resultBitmap = bitmap;
                                    resultX      = x;
                                    resultY      = y;
                                }
                            }
                        }
                    }
                }
            }

            //if (tiedForBest > 0)
            //	Console.WriteLine($"{_doubler} {tiedForBest}");

            return(resultBitmap != null);
        }
Beispiel #8
0
 public override void Reason()
 {
     if (!pieceProvided)
     {
         def           = _context.nextQueue.GetNext();
         pieceProvided = false;
     }
     _context.piece = _context.playfield.SpawnTileGroup(def, _context.spawnLocation);
     _machine.ChangeState <StateGravitate>().AddLine();
 }
Beispiel #9
0
 // for board reset when no more moves
 public void resetMe(PieceDefinition pieceType, int skinNum)
 {
     if (pd.ignoreReset)
     { // non-resettable piece
         return;
     }
     pd = pieceType;
     Debug.Log(pd.name);
     slotNum = skinNum;
     dressMe();
 }
        public void TwoPossibleOrientations()
        {
            var piece = new PieceDefinition("test", 0, 0, 0,
                                            new[]
            {
                "##"
            });

            Assert.Equal(2, piece.PossibleOrientations.Length);
            Assert.Equal(2, piece.TotalUsedLocations);
        }
        public void SinglePossibleOrientation()
        {
            var piece = new PieceDefinition("test", 0, 0, 0,
                                            new[]
            {
                "#"
            });

            Assert.Single(piece.PossibleOrientations);
            Assert.Equal(1, piece.TotalUsedLocations);
        }
Beispiel #12
0
    // spawn a new piece on the boar d itself (appear mode) which scales from small to big
    public void spawnNewAppear(PieceDefinition pd, float appearSpeed, int skinNum)
    {
        isActive = true;
        piece    = new GamePiece(pd, this, skinNum, position);
        piece.init();
        LeanTween.cancel(piece.thisPiece); // cancel any active tweens on this object
        float scaleSize = 0;

        scaleSize = piece.thisPiece.transform.localScale.x;
        piece.thisPiece.transform.localScale = Vector3.zero; // appear from scale 0
        LeanTween.value(piece.thisPiece, appearTweeningSubFunction, 0f, scaleSize, appearSpeed).setOnUpdateParam(piece.thisPiece);
    }
Beispiel #13
0
 // sets the piece that is here to be a special piece
 public void setSpecialPiece(PieceDefinition pd)
 {
     if (panel.pnd.hasStartingPiece)
     {
         piece.removePiece(1);
         if (pd.isSpecial)
         { // if it's a special type, define the appropriate skin
             piece.slotNum = pd.skinToUseDuringSpawn(arrayRef[0], arrayRef[1]);
         }
         piece.pd = pd; // sets the pd type
     }
 }
Beispiel #14
0
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY)
        {
            var holes = new List <int>();

            int leastHoles      = BoardState.Width * BoardState.Height;
            int largestHoleSize = 0;

            resultBitmap = null;
            resultX      = -1;
            resultY      = -1;


            //TODO: Distance could be < the piece size too
            for (var distance = 0; distance < BoardState.Width + BoardState.Height; distance++)
            {
                //TODO: Min(distance, Width - bitmap.MinSideSize) ?
                for (var x = 0; x <= distance; x++)
                {
                    var y = distance - x;

                    foreach (var bitmap in piece.PossibleOrientations)
                    {
                        if (x + bitmap.Width <= BoardState.Width && y + bitmap.Height <= BoardState.Height && board.CanPlace(bitmap, x, y))
                        {
                            var clone = board;
                            clone.Place(bitmap, x, y);

                            holes.Clear();
                            PlacementHelper.HoleCount(clone, ref holes);

                            //TODO: No Linq
                            if (holes.Count < leastHoles || (holes.Count == leastHoles && holes.Max() > largestHoleSize))
                            {
                                leastHoles      = holes.Count;
                                largestHoleSize = holes.Max();

                                resultBitmap = bitmap;
                                resultX      = x;
                                resultY      = y;
                            }
                        }
                    }
                }

                if (resultBitmap != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #15
0
 public override bool powerMatched(int posX1, int posY1, int posX2, int posY2, bool execute,
                                   PieceDefinition thisPd, PieceDefinition otherPd)
 {
     if (otherPd.isDestructible)
     {
         if (execute)
         {
             StartCoroutine(doPower6Merge(posX1, posY1, posX2, posY2));          // match 6 type power ( clears the entire board )
         }
         return(true);
     }
     return(false);
 }
Beispiel #16
0
 // for external scripts to call, destroys the game piece with validation checks
 public void destroy(int i)
 {
     if (pd != null)
     {
         if (!pd.isSpecial)
         {                                    // not a special piece... it is a colored piece
             master.gm.matchCount[slotNum]++; // increase the type count that is destroyed.
         }
         pd.onPieceDestroyed(this);           // call the piece type onDestroy function (if any)
         pd = null;                           // null the piece attribute here
         master.gm.animScript.doAnim(animType.GLOBALDESTROY, master.arrayRef[0], master.arrayRef[1]);
     }
     destroyCall(i);
 }
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY)
        {
            _evaluator.BeginEvaluation(board);

            resultBitmap = null;
            resultX      = -1;
            resultY      = -1;

            int bestScore = int.MinValue;

            //Exhaustively place it and make new child nodes
            for (var index = 0; index < piece.PossibleOrientations.Length; index++)
            {
                var bitmap       = piece.PossibleOrientations[index];
                var searchWidth  = BoardState.Width - bitmap.Width + 1;
                var searchHeight = BoardState.Height - bitmap.Height + 1;

                //TODO? If this is the first piece, remove mirrors/rotations from the children
                //if (isFirstPiece)
                //{
                //	//TODO: This doesn't stop diagonal mirrors
                //	searchWidth = (BoardState.Width - bitmap.Width) / 2 + 1;
                //	searchHeight = (BoardState.Height - bitmap.Height) / 2 + 1;
                //}

                for (int x = 0; x < searchWidth; x++)
                {
                    for (int y = 0; y < searchHeight; y++)
                    {
                        if (board.CanPlace(bitmap, x, y))
                        {
                            var clone = board;
                            clone.Place(bitmap, x, y);

                            var score = _evaluator.Evaluate(in clone, x, x + bitmap.Width, y, y + bitmap.Height);
                            if (score > bestScore)
                            {
                                resultBitmap = bitmap;
                                resultX      = x;
                                resultY      = y;

                                bestScore = score;
                            }
                        }
                    }
                }
            }

            return(resultBitmap != null);
        }
 /// <summary>
 /// Swaps out the internal piece for <paramref name="toHold"/> and outputs <paramref name="swapped"/>. Returns <see langword="true"/> when the swap is successful.
 /// </summary>
 /// <param name="toHold"></param>
 /// <param name="swapped"></param>
 /// <returns></returns>
 public bool Swap(PieceDefinition toHold, out PieceDefinition?swapped)
 {
     if (isLocked)
     {
         swapped = null;
         return(false);
     }
     else
     {
         swapped   = heldPiece;
         heldPiece = toHold;
         isLocked  = true;
         return(true);
     }
 }
Beispiel #19
0
 // reset the board when no more moves
 public void reset(PieceDefinition pd, int skinNum)
 {
     if (panel.isFillable())
     { // if the panel can hold a game piece
         if (isFilled)
         {
             piece.resetMe(pd, skinNum); // reset it
         }
         else
         { // game piece was stolen by another board and the reference is wrong. create a new piece
             piece = new GamePiece(pd, this, skinNum, position);
             piece.init();
         }
         isFalling = false;
         isActive  = true;
     }
 }
Beispiel #20
0
        /// <summary>
        /// Finds a placement (Not guaranteed to be any good) for the given piece on the given board
        /// </summary>
        public static void GetFirstPlacement(BoardState board, PieceDefinition piece, out PieceBitmap bitmap, out int x, out int y)
        {
            for (var index = 0; index < piece.PossibleOrientations.Length; index++)
            {
                bitmap = piece.PossibleOrientations[index];
                for (y = BoardState.Height - bitmap.Height; y >= 0; y--)
                {
                    for (x = BoardState.Width - bitmap.Width; x >= 0; x--)
                    {
                        if (board.CanPlace(bitmap, x, y))
                        {
                            return;
                        }
                    }
                }
            }

            throw new Exception("GetFirstPlacement couldn't find a placement");
        }
Beispiel #21
0
        /// <summary>
        /// This runs from the highest x/y backwards, as a rule of thumb placement strategies should try place starting at 0,0 so this is likely to finish quicker
        /// </summary>
        public static bool CanPlace(BoardState board, PieceDefinition piece)
        {
            for (var index = 0; index < piece.PossibleOrientations.Length; index++)
            {
                var bitmap = piece.PossibleOrientations[index];
                for (var y = BoardState.Height - bitmap.Height; y >= 0; y--)
                {
                    for (var x = BoardState.Width - bitmap.Width; x >= 0; x--)
                    {
                        if (board.CanPlace(bitmap, x, y))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #22
0
		private void BufferPiece(PieceDefinition piece)
		{
			for (var y = 0; y < 5; y++)
			{
				for (var x = 0; x < 5; x++)
				{
					bool here = false;
					if (piece.Bitmap.Width > x && piece.Bitmap.Height > y)
						here = piece.Boolmap[x, y];

					_lines[y].Append(here ? '#' : ' ');
				}

				_lines[y].Append(" | ");
			}

			_lines[5].Append($"$:{piece.ButtonCost.ToString().PadRight(3)} | ");
			_lines[6].Append($"T:{piece.TimeCost.ToString().PadRight(3)} | ");
			_lines[7].Append($"+:{piece.ButtonsIncome.ToString().PadRight(3)} | ");
		}
Beispiel #23
0
        protected override bool TryPlacePiece(BoardState board, PieceDefinition piece, out PieceBitmap resultBitmap, out int resultX, out int resultY)
        {
            foreach (var bitmap in piece.PossibleOrientations)
            {
                for (var y = 0; y <= BoardState.Height - bitmap.Height; y++)
                {
                    for (var x = 0; x <= BoardState.Width - bitmap.Width; x++)
                    {
                        if (board.CanPlace(bitmap, x, y))
                        {
                            resultBitmap = bitmap;
                            resultX      = x;
                            resultY      = y;
                            return(true);
                        }
                    }
                }
            }

            resultBitmap = null;
            resultX      = -1;
            resultY      = -1;
            return(false);
        }
Beispiel #24
0
        public double CalculateValueOfPurchasing(SimulationState state, int pieceIndex, PieceDefinition piece)
        {
            var offset = OffsetForPosition(state);

            var value = piece.TotalUsedLocations * _value[offset + UsedLocationUtilityOffset];

            value += piece.ButtonCost * _value[offset + ButtonCostUtilityOffset];

            value += piece.TimeCost * _value[offset + TimeCostUtilityOffset];

            //TODO: Should we have piece income and total income utilities?
            value += SimulationHelpers.ButtonIncomeAmountAfterPosition(state.PlayerPosition[state.ActivePlayer]) * piece.ButtonsIncome * _value[offset + IncomeUtilityOffset];

            value += SimulationHelpers.ButtonIncomeAmountAfterPosition(state.PlayerPosition[state.ActivePlayer]) * piece.ButtonsIncome * piece.ButtonsIncome * _value[offset + IncomeSquaredUtilityOffset];

            //TODO: Should this be boolean or vary by difference in location?
            if (state.PlayerPosition[state.NonActivePlayer] >= (state.PlayerPosition[state.ActivePlayer] + piece.TimeCost))
            {
                value += _value[offset + GetAnotherTurnUtilityOffset];
            }

            //TODO: Should this be boolean or vary by income amount?
            if (SimulationHelpers.ButtonIncomeAmountAfterPosition(state.PlayerPosition[state.ActivePlayer]) != SimulationHelpers.ButtonIncomeAmountAfterPosition(Math.Min(SimulationState.EndLocation, state.PlayerPosition[state.ActivePlayer] + piece.TimeCost)))
            {
                value += _value[offset + ReceiveIncomeUtilityOffset];
            }

            return(value);            //TODO Clamp? Divide by total utilities?
        }
Beispiel #25
0
 // old powerMatched function..
 public virtual bool powerMatched(int posX1, int posY1, int posX2, int posY2, bool execute,
                                  PieceDefinition pdMain, PieceDefinition pdSub)
 {
     return(false);        // default is nothing..
 }
Beispiel #26
0
 public void PlayerPurchasedPiece(int player, PieceDefinition piece)
 {
     _turn++;
     Console.WriteLine($"{_turn}) Player {player} purchased {piece.Name}");
 }
Beispiel #27
0
 public bool TryPlacePiece(BoardState board, PieceDefinition piece, in PieceCollection possibleFuturePieces, int possibleFuturePiecesOffset, out PieceBitmap bitmap, out int x, out int y)
 public double CalculateValueOfPurchasing(SimulationState state, int pieceIndex, PieceDefinition piece)
 {
     return(1);
 }
Beispiel #29
0
 protected abstract double CalculateValue(SimulationState state, int pieceIndex, PieceDefinition piece);
Beispiel #30
0
 protected override double CalculateValue(SimulationState state, int pieceIndex, PieceDefinition piece)
 {
     return(_calculator.CalculateValueOfPurchasing(state, pieceIndex, piece));
 }