// The first definition should be the root public GameStateDefinitionGraph(GameStateDefinition[] gameStateDefinitions) { this.gameStateDefinitions = gameStateDefinitions; nodeArray = new GameStateNode[gameStateDefinitions.Length]; for (int i = 0; i < gameStateDefinitions.Length; i++) { GameStateDefinition definition = gameStateDefinitions[i]; if (definition == null) { continue; } GameStateNode newNode = new GameStateNode(definition, i); if (root == null) { root = newNode; // only first node will apply this } nodeArray[i] = newNode; nodeDictionary.Add(definition, newNode); } foreach (var node in nodeArray) { node.PopulateNeighbors(FindGameStateNode); } }
public void MakeTree(){ CreateClone.SecondryUpdate (); root = new GameStateNode (null, CreateClone.getStates(), -1); /*foreach (playerStateNode p in root.entities.players) Debug.Log (p.pos + ", " + p.health + ", " + p.damage); foreach (playerStateNode p in root.entities.enemies) Debug.Log (p.pos + ", " + p.health + ", " + p.damage);*/ CreateChildren (root, depth); }
public int Iterate(GameStateNode node, int depth, int alpha, int beta, bool Player) { if (depth == 0 /*|| node.IsTerminal()*/) { return(node.GetTotalScore(pHealth, eHealth)); } if (Player == MaxPlayer) { int leaf = -1; int value = -100000; foreach (GameStateNode child in node.children) { value = Iterate(child, depth - 1, alpha, beta, !Player); if (alpha < value) { leaf = node.children.IndexOf(child); } alpha = Mathf.Max(alpha, value); if (beta < alpha) { break; } /*////////////// * if(alpha < Iterate(child, depth - 1, alpha, beta, !Player)){ * leaf = node.children.IndexOf(child); * } * ////////////// * alpha = Mathf.Max(alpha, Iterate(child, depth - 1, alpha, beta, !Player)); * if (beta < alpha){ * break; * } */ } if (depth == treeDepth) { return(leaf); } return(alpha); } else { foreach (GameStateNode child in node.children /*(Player)*/) { beta = Mathf.Min(beta, Iterate(child, depth - 1, alpha, beta, !Player)); if (beta < alpha) { break; } } return(beta); } }
public void MakeTree() { CreateClone.SecondryUpdate(); root = new GameStateNode(null, CreateClone.getStates(), -1); /*foreach (playerStateNode p in root.entities.players) * Debug.Log (p.pos + ", " + p.health + ", " + p.damage); * foreach (playerStateNode p in root.entities.enemies) * Debug.Log (p.pos + ", " + p.health + ", " + p.damage);*/ CreateChildren(root, depth); }
public void PopulateNeighbors(Func <GameStateDefinition, GameStateNode> getNeighborInstance) { System.Action <GameStateDefinition> declarationMethod = (definition) => { if (definition != null) { GameStateNode node = getNeighborInstance(definition); if (node != null) { neighbors.Add(node); } } }; gameStateDefinition.DeclareLinks(declarationMethod); }
public static void ChangeGameStateTo(GameState state) { if (currentState != GameState.Default) { GameStateNode lastNode = gameStatesDict[currentState]; if (lastNode.objectsOff != null && lastNode.objectsOff.Length > 0) { MassTurnOnOff(lastNode.objectsOff, false); } SetView(lastNode.view, false); switch (currentState) { case GameState.MainMenu: break; case GameState.InProgress: break; case GameState.GameOver: break; } } GameStateNode newNode = gameStatesDict[state]; if (newNode.objectsOn != null && newNode.objectsOn.Length > 0) { MassTurnOnOff(newNode.objectsOn, true); } currentState = state; switch (state) { case GameState.MainMenu: break; case GameState.InProgress: gameStarted = true; break; case GameState.GameOver: gameStarted = false; break; } SetView(newNode.view, true); }
public GameStateNode(GameStateNode _parent, ListState state, int movedIndex) { children = null; parent = _parent; if (parent == null) { enemysTurn = true; } else { enemysTurn = !parent.enemysTurn; } this.movedIndex = movedIndex; entities = state; }
public void CreateChildren(GameStateNode state, int depth){ if (depth == 0) { return; } List<playerStateNode> attackers; List<playerStateNode> defenders; state.children = new List<GameStateNode> (); CreateClone.updateHealth (state.entities, "Players"); CreateClone.updateHealth (state.entities, "Enemies"); if (state.enemysTurn) { attackers = state.entities.enemies; defenders = state.entities.players; } else { defenders = state.entities.enemies; attackers = state.entities.players; } for(int i = 0; i < attackers.Count; ++i){ for(int j = 0; j < defenders.Count; ++j){ List<position> possibleMoves; string type = CreateClone.EntityType(!state.enemysTurn, i); if(type == "attacker"){ possibleMoves = attacker (CreateClone.entityRange(!state.enemysTurn, i), defenders[j].pos); } else if(type == "healler"){ possibleMoves = healler (defenders[j].pos); } else {//if(type == "diagnoller"){ possibleMoves = diagnoller (defenders[j].pos); } foreach(position pos in possibleMoves){ //Debug.Log(pos); if(!CanGoTo(pos, ref state.entities)) continue; CreateClone.UpdatePos(!state.enemysTurn, i, pos); CreateClone.attack(!state.enemysTurn, i); state.children.Add(new GameStateNode (state, CreateClone.getStates(), i)); CreateChildren(state.children[state.children.Count-1], depth-1); CreateClone.updateHealth (state.entities, "Players"); CreateClone.updateHealth (state.entities, "Enemies"); } } } }
public int Iterate(GameStateNode node, int depth, int alpha, int beta, bool Player){ if (depth == 0 /*|| node.IsTerminal()*/){ return node.GetTotalScore(pHealth, eHealth); } if (Player == MaxPlayer){ int leaf = -1; int value = -100000; foreach (GameStateNode child in node.children){ value = Iterate(child, depth - 1, alpha, beta, !Player); if(alpha < value){ leaf = node.children.IndexOf(child); } alpha = Mathf.Max (alpha, value); if (beta < alpha){ break; } /*////////////// if(alpha < Iterate(child, depth - 1, alpha, beta, !Player)){ leaf = node.children.IndexOf(child); } ////////////// alpha = Mathf.Max(alpha, Iterate(child, depth - 1, alpha, beta, !Player)); if (beta < alpha){ break; } */ } if(depth == treeDepth) return leaf; return alpha; } else{ foreach (GameStateNode child in node.children/*(Player)*/){ beta = Mathf.Min(beta, Iterate(child, depth - 1, alpha, beta, !Player)); if (beta < alpha){ break; } } return beta; } }
public GameStateNode(GameStateNode _parent, ListState state, int movedIndex){ children = null; parent = _parent; if (parent == null) enemysTurn = true; else enemysTurn = !parent.enemysTurn; this.movedIndex = movedIndex; entities = state; }
public override void update(float time, Graphics g) { if (runnable) { // We set up the gunnode to allow it to shoot again GunControlNode gunctrlnode = null; GameStateNode gstatenode = null; SpaceShipCollisionNode sscn = null; EnemyBlockNode eblocknode = null; if (lst_gun.Count > 0) { gunctrlnode = (GunControlNode)lst_gun.First(); } if (lst_game.Count > 0) { gstatenode = (GameStateNode)lst_game.First(); } if (lst_block.Count > 0) { eblocknode = (EnemyBlockNode)lst_block.First(); } #region bullet bunker collision foreach (Node bullet in lst_bullet.ToList()) // to list to remove entity while looping { foreach (Node bunker in lst_bunker.ToList()) { BulletCollisionNode bullcn = (BulletCollisionNode)bullet; BunkerCollisionNode bunkcn = (BunkerCollisionNode)bunker; if (bunkcn.bunker.life > 0 && CheckRectangleCollision(bullcn.display, bullcn.pos, bunkcn.display, bunkcn.pos) && CheckPixelCollision(bullcn.display, bullcn.pos, bunkcn.display, bunkcn.pos) ) { CheckPixelCollision(bullcn.display, bullcn.pos, bunkcn.display, bunkcn.pos, bullcn.bullet.damage); bunkcn.bunker.life -= pixel_destroyed; pixel_destroyed = 0; if (gunctrlnode != null && bullcn.bullet.ally) { gunctrlnode.gun.shoot = true; } ef.removeEntity(bullcn.entity); } } } #endregion #region enemy bullet collision gstatenode.gs.enemiesCount = lst_enemy.Count; foreach (Node bullet in lst_bullet.ToList()) // to list to remove entity while looping { foreach (Node enemy in lst_enemy.ToList()) { BulletCollisionNode bullcn = (BulletCollisionNode)bullet; EnemyNode en = (EnemyNode)enemy; if (en.enemy.life > 0 && bullcn.bullet.ally && CheckRectangleCollision(bullcn.display, bullcn.pos, en.display, en.pos) && CheckPixelCollision(bullcn.display, bullcn.pos, en.display, en.pos) ) { ef.removeEntity(bullcn.entity); en.enemy.life -= 1; if (en.enemy.life <= 0) { if (gstatenode != null) { switch (en.enemy.type) { case Enemy.Type.Big: gstatenode.gs.score += 500; break; case Enemy.Type.Medium: gstatenode.gs.score += 300; break; case Enemy.Type.Small: gstatenode.gs.score += 100; break; } } ef.removeEntity(en.entity); } pixel_destroyed = 0; if (gunctrlnode != null) { gunctrlnode.gun.shoot = true; } if (Game.rand.Next(20) == 1) // Drop a bonus { Array values = Enum.GetValues(typeof(Bonus.Type)); ef.CreateBonus(en.pos, (Bonus.Type)values.GetValue(Game.rand.Next(values.Length))); } } } } #endregion #region spaceship bullet collision if (lst_spaceship.Count > 0) { sscn = (SpaceShipCollisionNode)lst_spaceship.First(); foreach (Node bullet in lst_bullet.ToList()) { BulletCollisionNode bullcn = (BulletCollisionNode)bullet; if (sscn.spaceship.life > 0 && !bullcn.bullet.ally && CheckRectangleCollision(bullcn.display, bullcn.pos, sscn.display, sscn.pos) && CheckPixelCollision(bullcn.display, bullcn.pos, sscn.display, sscn.pos) ) { ef.removeEntity(bullcn.entity); sscn.spaceship.life -= bullcn.bullet.damage; gstatenode.gs.lives = sscn.spaceship.life; pixel_destroyed = 0; } } } #endregion #region bullet bullet collision foreach (Node bullet in lst_bullet.ToList()) // to list to remove entity while looping { foreach (Node bull in lst_bullet.ToList()) { BulletCollisionNode bullcn = (BulletCollisionNode)bullet; BulletCollisionNode en = (BulletCollisionNode)bull; if (bullcn.entity.Name != en.entity.Name) { if ( CheckRectangleCollision(bullcn.display, bullcn.pos, en.display, en.pos) && CheckPixelCollision(bullcn.display, bullcn.pos, en.display, en.pos) ) { ef.removeEntity(bullcn.entity); ef.removeEntity(en.entity); if (gunctrlnode != null) { gunctrlnode.gun.shoot = true; } } } } } #endregion #region spaceship bonus collision if (lst_spaceship.Count > 0) { sscn = (SpaceShipCollisionNode)lst_spaceship.First(); foreach (Node bonus in lst_bonus.ToList()) { BonusCollisionNode bonusn = (BonusCollisionNode)bonus; if (sscn.spaceship.life > 0 && CheckRectangleCollision(bonusn.display, bonusn.pos, sscn.display, sscn.pos) && CheckPixelCollision(bonusn.display, bonusn.pos, sscn.display, sscn.pos) ) { switch (bonusn.bonus.type) { case Bonus.Type.PlusLife: sscn.spaceship.life++; bonus_label = "+ 1 life"; break; case Bonus.Type.ScoreBoost: gstatenode.gs.score *= 2; bonus_label = "Score doubled"; break; case Bonus.Type.RestoreBunker: foreach (Node bunker in lst_bunker.ToList()) { ef.removeEntity(bunker.entity); } ef.CreateBunkerEntities(size); bonus_label = "Bunker restored"; break; case Bonus.Type.EnemySlow: foreach (Node enemy in lst_enemy.ToList()) { EnemyNode enem = (EnemyNode)enemy; enem.enemy.vitesse.x /= 5; } bonus_label = "Enemies slowdown"; break; case Bonus.Type.doubleShoot: Gun gun = (Gun)sscn.entity.GetComponent("Gun"); gun.doubleShoot = true; bonus_label = "Double bullet"; break; case Bonus.Type.controlledBullet: Gun pisto = (Gun)sscn.entity.GetComponent("Gun"); pisto.controllableShoot = true; bonus_label = "Controlled Bullet"; break; } Console.WriteLine(bonus_label); ef.removeEntity(bonusn.entity); bonus_sound.Play(); gstatenode.gs.lives = sscn.spaceship.life; pixel_destroyed = 0; } } if (g != null && compteur_label++ < 1000) { g.DrawString( bonus_label, Game.font, Game.blackBrush, size.Width - 130, size.Height - 50 ); } else if (g != null && compteur_label++ > 200) { compteur_label = 0; bonus_label = ""; } } #endregion #region enemyblock collision if (eblocknode.block.direction == EnemyBlock.Direction.Left && eblocknode.block.upperLeft.x <= 0) { eblocknode.block.collided = true; eblocknode.block.direction = EnemyBlock.Direction.Right; eblocknode.block.shootProbability -= 10; } else if (eblocknode.block.direction == EnemyBlock.Direction.Right && eblocknode.block.bottomRight.x >= size.Width) { eblocknode.block.collided = true; eblocknode.block.direction = EnemyBlock.Direction.Left; eblocknode.block.shootProbability -= 10; } if (lst_spaceship.Count > 0) { sscn = (SpaceShipCollisionNode)lst_spaceship.First(); // we check the collision we the spaceship and then set the game to lose if collision occured if ( sscn.pos.point.x + sscn.display.bitmap.Width >= eblocknode.block.upperLeft.x && sscn.pos.point.x <= eblocknode.block.bottomRight.x && sscn.pos.point.y + sscn.display.bitmap.Height >= eblocknode.block.upperLeft.y && sscn.pos.point.y <= eblocknode.block.bottomRight.y ) { gstatenode.gs.state = Game.State.Lost; } } #endregion } }
public override void update(float time, Graphics g) { if (runnable) { EnemyBlockNode ben = (EnemyBlockNode)lst_block.First(); GameStateNode gsn = (GameStateNode)lst_game.First(); foreach (Node node in lst) { GunControlNode gcn = (GunControlNode)node; if (keyPool.Contains(gcn.gunControl.space) && gcn.gun.shoot) { gcn.gun.shootingPoint = gcn.pos.point + new Vector2D(gcn.display.bitmap.Width / 2, 0); sp.Play(); gcn.gun.shoot = false; keyPool.Remove(gcn.gunControl.space); if (gcn.gun.doubleShoot && timer_bonus < 5) { timer_bonus++; } else { timer_bonus = 0; gcn.gun.doubleShoot = false; } ef.CreateSpaceShipBullet(gcn.gun); } } // we update enemies gun shooting point foreach (Node enemy in lst_enemies) { EnemyNode en = (EnemyNode)enemy; en.gun.shootingPoint = en.pos.point + new Vector2D(en.display.bitmap.Width / 2, 0); } // we see if we shoot anything, if so we choose a random enemy to do so if (Game.rand.Next(ben.block.shootProbability) <= gsn.gs.level * 2) { int index = Game.rand.Next(lst_enemies.Count); if (lst_enemies.Count > 0) { EnemyNode en = (EnemyNode)lst_enemies.ToList()[index]; int damage = 0; Bitmap b = null; switch (en.enemy.type) { case Enemy.Type.Big: b = Properties.Resources.shoot4; damage = 3 + gsn.gs.level; break; case Enemy.Type.Medium: damage = 2 + gsn.gs.level; b = Properties.Resources.shoot3; break; case Enemy.Type.Small: b = Properties.Resources.shoot2; damage = 1 + gsn.gs.level; break; } ef.CreateEnemyBullet(en.gun, b, damage); } } } }
public List <GameStateDefinition> FindPathToGameState(GameStateDefinition current, GameStateDefinition destination) { if (current == null || destination == null) { throw new NullReferenceException("Trying to find path to game state, but the method was called with null arguments"); } // ___________________________________________ Variable setup ___________________________________________ // GameStateNode startNode = nodeDictionary[destination]; int[] distances = new int[nodeArray.Length]; GameStateNode[] previous = new GameStateNode[nodeArray.Length]; List <GameStateNode> queue = new List <GameStateNode>(nodeArray); for (int i = 0; i < distances.Length; i++) { distances[i] = int.MaxValue - 1; } distances[startNode.index] = 0; // ___________________________________________ Helper methods ___________________________________________ // int DistanceTo(GameStateNode node) { return(distances[node.index]); } void SetDistanceTo(GameStateNode node, int dist) { distances[node.index] = dist; } void SetPrevTo(GameStateNode node, GameStateNode prev) { previous[node.index] = prev; } GameStateNode PopNodeWithLowestDist() { int record = int.MaxValue; GameStateNode recordHolder = null; int recordI = -1; for (int i = 0; i < queue.Count; i++) { if (DistanceTo(queue[i]) < record) { record = DistanceTo(queue[i]); recordHolder = queue[i]; recordI = i; } } queue.RemoveAt(recordI); return(recordHolder); } // ___________________________________________ Algo ___________________________________________ // while (queue.Count > 0) { GameStateNode u = PopNodeWithLowestDist(); int fullPathLengthToNeighborsOfU = DistanceTo(u) + 1; for (int i = 0; i < u.neighbors.Count; i++) { if (fullPathLengthToNeighborsOfU < DistanceTo(u.neighbors[i])) { SetDistanceTo(u.neighbors[i], fullPathLengthToNeighborsOfU); SetPrevTo(u.neighbors[i], u); } } } // ___________________________________________ Build path ___________________________________________ // GameStateNode toAdd = nodeDictionary[current]; List <GameStateDefinition> path = new List <GameStateDefinition>(); while (toAdd != null) { path.Add(toAdd.gameStateDefinition); toAdd = previous[toAdd.index]; } return(path); }
public override void update(float time, Graphics g) { GameStateNode gsn = (GameStateNode)lst.First(); if (runnable && gsn != null) { switch (gsn.gs.state) { case Game.State.Begin: // We display the begin if (g != null) { g.Flush(); g.DrawImage(Properties.Resources.start, size.Width / 3, size.Height / 4); } if (keyPool.Contains(Keys.S)) { // We launch every system ef.CreateDisplaybleEntity(size, gsn.gs.lives); ef.CreateBunkerEntities(size); ef.CreateEnemyEntities(size, gsn.gs); foreach (Systeme sys in engine.GetSystems()) { sys.Start(); } keyPool.Remove(Keys.S); gsn.gs.state = Game.State.Play; } break; case Game.State.Pause: if (g != null) { g.DrawImage(Properties.Resources.pause, size.Width / 4, size.Height / 4); } if (keyPool.Contains(Keys.P)) { // We launch every system foreach (Systeme sys in engine.GetSystems()) { sys.Start(); } keyPool.Remove(Keys.P); gsn.gs.state = Game.State.Play; } break; case Game.State.Play: if (keyPool.Contains(Keys.P)) { //We pause useless system foreach (Systeme sys in engine.GetSystems()) { if (sys.ClassId != "GameStateSystem") { sys.Stop(); } } keyPool.Remove(Keys.P); gsn.gs.state = Game.State.Pause; } if (g != null) { g.DrawString("Nombre de vie : " + gsn.gs.lives + " / Points : " + gsn.gs.score + " / Level : " + gsn.gs.level, Game.font, Game.blackBrush, 10, size.Height - 50 ); } if (gsn.gs.lives <= 0) { gsn.gs.state = Game.State.Lost; } else if (gsn.gs.enemiesCount <= 0) { gsn.gs.state = Game.State.Win; } break; case Game.State.Win: foreach (Systeme sys in engine.GetSystems()) { if (sys.ClassId != "GameStateSystem") { sys.Stop(); } } if (g != null) { g.DrawImage(Properties.Resources.you_win, size.Width / 3, size.Height / 3); g.DrawString("Press 'n' to go to the next level", Game.font, Game.blackBrush, size.Width / 2, size.Height - 50 ); } if (keyPool.Contains(Keys.N)) { gsn.gs.level++; // next level keyPool.Remove(Keys.N); foreach (Entity ent in ef.GetEntities().ToList()) { if (ent.Name != "game") { ef.removeEntity(ent); } } gsn.gs.state = Game.State.Begin; } break; case Game.State.Lost: if (g != null) { g.DrawImage(Properties.Resources.game_over, size.Width / 4, size.Height / 4); g.DrawString("Press 'r' to restart", Game.font, Game.blackBrush, size.Width / 2, size.Height - 50 ); } foreach (Systeme sys in engine.GetSystems()) { if (sys.ClassId != "GameStateSystem") { sys.Stop(); } } if (keyPool.Contains(Keys.R)) { gsn.gs.level = 1; gsn.gs.score = 0; gsn.gs.lives = 3; keyPool.Remove(Keys.R); foreach (Entity ent in ef.GetEntities().ToList()) { if (ent.Name != "game") { ef.removeEntity(ent); } } gsn.gs.state = Game.State.Begin; } break; } } }
public void CreateChildren(GameStateNode state, int depth) { if (depth == 0) { return; } List <playerStateNode> attackers; List <playerStateNode> defenders; state.children = new List <GameStateNode> (); CreateClone.updateHealth(state.entities, "Players"); CreateClone.updateHealth(state.entities, "Enemies"); if (state.enemysTurn) { attackers = state.entities.enemies; defenders = state.entities.players; } else { defenders = state.entities.enemies; attackers = state.entities.players; } for (int i = 0; i < attackers.Count; ++i) { for (int j = 0; j < defenders.Count; ++j) { List <position> possibleMoves; string type = CreateClone.EntityType(!state.enemysTurn, i); if (type == "attacker") { possibleMoves = attacker(CreateClone.entityRange(!state.enemysTurn, i), defenders[j].pos); } else if (type == "healler") { possibleMoves = healler(defenders[j].pos); } else //if(type == "diagnoller"){ { possibleMoves = diagnoller(defenders[j].pos); } foreach (position pos in possibleMoves) { //Debug.Log(pos); if (!CanGoTo(pos, ref state.entities)) { continue; } CreateClone.UpdatePos(!state.enemysTurn, i, pos); CreateClone.attack(!state.enemysTurn, i); state.children.Add(new GameStateNode(state, CreateClone.getStates(), i)); CreateChildren(state.children[state.children.Count - 1], depth - 1); CreateClone.updateHealth(state.entities, "Players"); CreateClone.updateHealth(state.entities, "Enemies"); } } } }
public override void update(float time, Graphics g) { if (runnable) { #region basics movement GunControlNode gunnode = (GunControlNode)lstgun.First(); foreach (Node n in lstmovement.ToList()) // We transform to list to entity from node { MovementNode mn = (MovementNode)n; Velocity v = mn.vitesse; Position p = mn.pos; Vector2D newv = time * v.speedVect + p.point; if (newv.x < size.Width || newv.x > 0) { p.point = newv; } if (newv.y < 0) { factory.removeEntity(mn.entity); gunnode.gun.shoot = true; } else if (newv.y > size.Height) { factory.removeEntity(mn.entity); } } #endregion #region enemies movement GameStateNode gstatenode = null; EnemyBlockNode eblocknode = null; if (lst_game.Count > 0) { gstatenode = (GameStateNode)lst_game.First(); } if (lst_block.Count > 0) { eblocknode = (EnemyBlockNode)lst_block.First(); } // First we move enemies int compteur = 0; foreach (Node enemies in lst_enemies) { EnemyNode en = (EnemyNode)enemies; switch (eblocknode.block.direction) { case EnemyBlock.Direction.Right: en.pos.point.x += en.enemy.vitesse.x * time + (gstatenode.gs.level * time); break; case EnemyBlock.Direction.Left: en.pos.point.x -= en.enemy.vitesse.x * time + (gstatenode.gs.level * time); break; } if (eblocknode.block.collided) { if (time == 0) { time = (float)0.005; // In case the draw update happens at impact } en.pos.point.y += en.enemy.vitesse.y * time; en.enemy.vitesse.y += size.Width / 10 + (gstatenode.gs.level * time); en.enemy.vitesse.x += 3 * gstatenode.gs.level; } } if (eblocknode.block.collided) { eblocknode.block.collided = false; } updateEnemyBlock(eblocknode); #endregion } }