SODA and Finite State Machines

Hello All, I hope everyone is at least as well as the last time I posted on here, hopefully even better. I wanted to write here today to update on my current projects. I am happy to announce that Liquidators, a yearlong project I have been lucky enough to be the lead producer of, has released a playable and open demo, for free. I would love to have support from my site and receive feedback on this game! It is a survival horror game based on the real life events which followed the reactor meltdown at Chernobyl. The demo can be downloaded HERE.

I will of course keep my site in the loop about this game, as we plan for a steam release this summer, hopefully. However, this is a site dedicated to my personal code and projects so I will carry on to stuff that you will definitely find less interesting than a nuclear reactor survival horror game which is literally free right up there ^. You could play it for FREE but you’re still reading this? Fine, if you’ve made it this far lets talk about scriptable objects and how I’ve been using them in my Finite State Machines in a separate, yet still cool, side project.

A little about this “side” project:

Been in production for almost 3 weeks

I’m working as the only engineer, Game being built in Unity, Being built for gamepad controllers (using primitive input system (I know))

it’s a 2 player endless runner

Player 1(Dog) can choose when to throw player 2(Boomerang)

Boomerang player aims themselves before throw

Dog player only has control of left and right movement, constantly moving forward

Boomerang player can control left, right, and forward back, still constantly moving forward, just at adjusted rate

Players try to survive as long as possible

Each have abilities they can use to help each other

“Tokens” used when using ability

Cylinder is enemy only boomeang can kill, kills dog. Wall blockades kill both

Here’s a clip:

So here, you could imagine there are a few player states. Specifically, a state for each player when the boomerang is with the dog, for when the dog and boomerang are separate, and for when the boomerang dies and the dog persists. A Finite State Machine helps us out here because none of these states will be coexisting. So, each player will have their own instance of a StateMachine, which takes an iState, and they must communicate with one another, to ensure they are in proper states at all times, since one of their states being out of sync would inherently break the other’s state (since their controls are dependent upon one another).

If you have read my other posts here , or here, or here, or here or- okay you get it.. If you’ve seen those posts or the title of this one, you know that I love SODA. So given our state machine above, SODA fits into this very well. The first issue presented above is that our state machines must know the state of one another. SODA Events really help us with this here. When the dog throws the boomerang, it’s an event. The dog script doesn’t even communicate with the boomerang script directly. It simply invokes that event, and the GameEventListener on the Boomerang is quick to respond, switching to its “free” state, after a throwing thread, of course. This exists for all my state transitions here, except for the boomerang being caught by the Dog for that requires a synchronous tap of a button by both players. But you can see how that would ensure our State machine stay in our intended state.

The next BIG help from SODA in these FSMs is that my IntVariable type, the Scriptable Object int I’ve made, can be passed into my states, where they have free access to the value they need, and receive all live updates to that number via that reference. Confused? Imagine this: My dog player location is stored in my Vector3Variable Scriptable Object. In my state constructor, I take a type Vector3Variable _playerLocation. Now _playerLocation.value will be a reference to the exact spot in memory where my Player Location value is stored. Whether I just want to access it, or even adjust it, that value is live, and feeding into any other script that may need that live number. This is huge because normally I would have to make a reference to my player in every script that needs that number, and store it again in that script. Furthermore, by taking it in the state constructor, I don’t have to pester my player script to retrieve it every frame, because in the case of a value that is changed elsewhere, my state script will receive that update instantly through the magic of SODA!

I hope this makes sense, but in case it doesn’t, here’s some code:


//This is a state for player 1's movement, while the boomerang is in its backpack
//Here you have my declaration of the Variables I will need in this State
//Protecting these variables calmed down an empty value warning I was gettig
    protected Vector3Variable _dogLocation;
    
//Player speed can be changed at any time
    protected FloatVariable _playerSpeed;

//Player can move, or not
    protected BoolVariable _playerCanMove;

//Reference to Dog script
    protected DogPlayerMovement _player;

//Constructor
public ISDogRunning (Vector3Variable dogLocation, FloatVariable playerSpeed, BoolVariable playerCanMove, DogPlayerMovement player)
    {
//Simply taking the references I have, and setting equal to the Variable I need
        _dogLocation = dogLocation;
        _playerSpeed = playerSpeed;
        _playerCanMove = playerCanMove;
        _player = player;
    }

//.............................

//This is my state Tick, run every frame
public void OnStateTick ()
    {
        if (_playerCanMove.value)
        {
            //Moves player forwards
            _player.transform.Translate (Vector3.forward * Time.deltaTime * _playerSpeed);

            //Allows player to move LR
            _player.transform.Translate (Vector3.right * Time.deltaTime * Input.GetAxis ("P1Left Stick Horizontal") * horizontalMovementMod);

            //Throw boomerang when A pressed
            //Keyboard controls for debug
            if (Input.GetButtonDown ("P1A Button") || Input.GetKeyDown (KeyCode.E))
            {
                //Tells player to throw
                _player.BoomerangThrown (aimLocation);
            }

            //Reads for player using ability
            if (Input.GetButtonDown ("P1B Button") || Input.GetKeyDown (KeyCode.R))
            {
                _player.UseSelectedDogAbility ();
            }

            //Allows player to switch through abilities
            if (Input.GetButtonDown ("P1X Button") || Input.GetKeyDown (KeyCode.F))
            {
                _player.SwitchDogAbility ();
            }
        }

        //Gets player's aim
        //This state actually reads input from player 2 as well, as aiming component was initially part of dog
        //Axis is between -1 and 1, adding 1 and then dividing by 2 to get complete input
        aimLocation = Vector3.Lerp (_player.GetLeftAimLimit (), _player.GetRightAimLimit (), ((Input.GetAxis ("P2Left Stick Horizontal")) + 1) / 2);

        //Will rotate arrow assigned to plauer
        arrowGO.transform.LookAt (aimLocation);

        //Puts aim point at aim locations
        aimPointGO.transform.position = aimLocation;

        //Updates player's location
        _dogLocation.value = _player.transform.position;
    }

Frogger Remake & SODA

Hello all, I hope that this blog post finds you all well. Given the COVID-19 circumstances, I (and everyone I know) have been pushed into online classrooms. It’s been fine, but luckily it has also given me some personal time to try and post on this site, and work on more personal projects… That being said this post is a class project by Nicole Havin, and myself. Nicole worked on the mostly on the aesthetic side of things, implementing sounds, Timer UI and Main menu. I’m writing this post to talk more about Scriptable Object Dependent Architecture. I’m posting this game here to provide my readers with an opportunity to experience the architecture of which I will be writing about.

Disclaimers: I do not own anything in this game

This is a remake, for a class project, of Konami’s 1981 classic “Frogger”

https://simmer.io/@aidantakami/~bcd44750-53b0-3b08-07fd-bcb7b3778673

This game is buggy and was made under a time crunch for class. I am only posting this game here to give examples of the architecture I am speaking of, and showing how it is used in this specific build. I am also experimenting with UnityWebGL and trying to get those games hosted here on my site. For those who don’t know, exporting to UnityWebGL carries with it a plethora of issues in how the game in converted to be playable via a browser. There are certainly lots of bugs which I have not run into on the WebGL version. So please consider this as you play this game! Please feel free to contact me if you find any bugs! If this goes well I will continue to try and import playable demos of the architecture of which I’m writing about. Give it a few plays through and I’ll catch you on the other side.

This short experience is build to be modular, easily debuggable, and dependency free through the use of SODA Game Events & Listeners, and SODA Variables.

I’d like to first draw your attention to how when the player is in the first half of the map they must avoid collisions. Collisions here are from incoming cars, which are deadly to frogger. However, the second half of the map, this is flipped. The second half of the map the player must seek collisions. Collisions in the latter half of the map are from the stable log platforms or the finish line colliders.

So how might we “normally” do this? I would say it would involve an edge trigger collider that would tell the player script that it needs to collide or else die. But alas, the eternal game dev issue of detecting if something isn’t there, in this case that something would be the log. I don’t want to get into how we might complete “this” way of solving the issue, but it’s just messy and involves heavy dependencies.

What is the SODA way of doing this? I appreciate you asking. Imagine if we could just have a Scriptable Object which holds a bool value, and we call it BoolVariable “isOverWater”. We set up a collider at the edge of land and water and have that trigger toggle between the 2 states of isOverWater, true and false. Now how do we get logs in there? Simple, the same thing, just have a single BoolVariable, playerIsOnMe, which all log prefabs reference. Does that make sense? This single variable is being operated on by all instances of the log prefab. These logs simply set the variable to true OnTriggerEnter() and to false OnTriggerExit(). Here’s that code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LogScript : MonoBehaviour
{

    //BoolVariable to represent if player is on this log
    public BoolVariable playerIsOnMe;

    //Used for spawning purposes
    private bool startsOnRight;
    public SpriteRenderer sr;

    //Used to move the player when on log
    [SerializeField]public IntVariable logSpeedToPlayer;
    [SerializeField] public int logSpeed;


    //Flips sprite depending on start side
    private void Start()
    {
        if(transform.position.x > 0)
        {
            startsOnRight = true;
            sr = gameObject.GetComponent<SpriteRenderer>();
            sr.flipX = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        //Moves the log in accordance to where it was spawned
        if (!startsOnRight)
        {
            transform.position += transform.right * logSpeed * Time.deltaTime;
        }
        else
        {
            transform.position -= transform.right * logSpeed * Time.deltaTime;
        }
    }


    public void OnTriggerEnter2D(Collider2D col)
    {
        //Player enters log
        if (col.gameObject.CompareTag("Player"))
        {
            //Set BoolVariable value
            Debug.Log("Player is on");
            playerIsOnMe.SetValue(true);

            //Gives this logs speed to the IntVariable which gives it to the Player
            if (!startsOnRight)
            {
                logSpeedToPlayer.SetValue(logSpeed);
            }
            else
            {
                logSpeedToPlayer.SetValue(-logSpeed);
            }
        }
        
    }

    public void OnTriggerExit2D(Collider2D col)
    {
        //Player Leaves Log
        if (col.gameObject.CompareTag("Player"))
        {
            Debug.Log("Player is off");
            playerIsOnMe.SetValue(false);
            logSpeedToPlayer.SetValue(0);
        }
        
    }
}

If this makes any sense to you, then odds are you can understand what is going on in the rest of this script (beyond the OnTriggers), but more on that later. The main note here is that when the player enters the log, beneath the Debug statement, the BoolVariable playerIsOnMe is set to true. This lets the player movement script know to continue displaying the idle sprite, this bool lets the GameManager know the player is still alive. These BoolVariables (playerIsOnMe and isOverWater) are both accessible by all other scripts, and never providing conflicting values because all scripts are refrencing the same ScriptableObject.

How are these two BoolVariables being compared? Once again, well thought out question. So since both these Bools are being determined elsewhere in the script, our PlayerMovement script, which also serves as the animator controller, simply has to reference these 2 variables values to know the state of the player. I did this in Frogger by having an event at the end of every “Jump” animation which would check the state of the 2 BoolVariables, as at the end of the Jump animation the player would either be securely on a log or dead.

About the IntVariables: If you understand the above architecture then you’ll enjoy knowing what’s going on with the IntVariable logSpeedToPlayer in the above code. Basically, that IntVariable, when set to 0, will not affect the player’s movement at all. When set to x it will apply a constant drag to the player to the right to simulate the effect of the player being on the log. So… Do you see why this is so rad? I can just SET THIS INT in my LOG SCRIPT and then my player will INSTANTLY BE EFFECTED by the change to this variable! COME ON!!! How Cool?! So notice that logspeed is just a regular int, but it is used to set the value of logSpeedToPlayer when needed. For now, that’s it! I will try to be more present on here, but I’m busy! But I hope you enjoy! and stay safe!

Game Sample: Converse Method

This is a method from a game I worked on. The method takes 6 strings, 1 representing a possible prompt, and then the others are possible responses, and returns the char selected by the user.

This method is used in my text based game to format dialogue, take a response, and return the letter answered. The method can be sent empty strings for answers which are not relevant, and will dispose of them, not allowing a user to pick them as an answer.

Screen Shot 2018-01-28 at 11.39.59 AMScreen Shot 2018-01-28 at 11.43.15 AM

char converse(string statement, string responseA, string responseB, string responseC, string responseD, string responseE){

    //char to be returned, representing answer. then sleeps to create pause
    char answer;
    sleep(3);

    //bools to represent that the letter chosen is valid
    bool answerB = false;
    bool answerC = false;
    bool answerD = false;
    bool answerE = false;

    //question posed
    cout << endl << endl << statement << endl << endl << endl;

    //possible responses
    cout << "A. " << responseA << endl;           //if there are multiple possible responses, this will trigger and set the corresponding bool to true. //B if(responseB.length() > 0){
        cout << "B. " << responseB << endl; answerB = true; } //C if(responseC.length() > 0){
        cout << "C. " << responseC << endl; answerC = true; } //D if(responseD.length() > 0){
        cout << "D. " << responseD << endl; answerD = true; } //E if(responseE.length() > 0){
        cout << "E. " << responseE << endl; answerE = true;     } //loop to allow user to make invalid entry while(true){ //stores user's answer in "answer" char cin >> answer;
        answer = tolower(answer);
//swtich statement to return user's response
        switch(answer){
            //if user answers:
            case 'a':
                return 'a';
                break;
            //if user answers:
            case 'b':
                if(answerB == true) return 'b';
                else break;
            //if user answers:
            case 'c':
                if(answerC == true) return 'c';
                else break;
            //if user answers:
            case 'd':
                if(answerD == true) return 'd';
                else break;
            //if user answers:
            case 'e':
                if(answerE == true) return 'e';
                else break;
            //otherwise, loop again
            default:
                break;
        }

        cout << "INVALID RESPONSE. Please choose a valid response" <<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>< endl;
    }
}
</pre>

Unity Sample: Scripts for Object Interaction in C#

The following are 2 scripts that I have written to allow a user using a first person camera in Unity to interact with “intractable” objects. Right now, the code doesn’t do much, it’s really just a template. If attached to an object with a rigidBody component, the interact script will simply turn the object red when it is within interacting range (in this case, 1 meter) and on the pressing of ‘e’ it will make the object jump.

Essentially, this is just a skeleton for object interaction. Attatching the Select script to the first person camera object and the interact script to an object, such as a door, would enable a user to input an “opening” and “closing” animation to the door when the key ‘e’ is pressed.

While the object is out of range

Screen Shot 2018-01-28 at 11.56.01 AM.png

While the object is in rangeScreen Shot 2018-01-28 at 11.57.11 AM

This object’s specific interactionScreen Shot 2018-01-28 at 12.00.40 PM.png

using UnityEngine;
using System.Collections;

public class Select : MonoBehaviour {
	public RaycastHit hit;

	// Use this for initialization
	void Start () {

	}

	// Update is called once per frame
	void Update () {

		//create a ray from the center of the screen
		Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2,0));

		//if the ray hits something within 1 meters, do:
		if (Physics.Raycast (ray, out hit, 1)) {

			//Checks to see if Interact script is attatched to the object being looked upon
			if (hit.collider.gameObject.GetComponent () != null) {

				//Calls the OnLookEnter funtion for the object with this script attatched
				hit.collider.gameObject.GetComponent ().OnLookEnter ();

			}
		} 

		//When not being looked at
		else {

			Interact.OnLookExit ();
		}
	}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Interact : MonoBehaviour {
	static public bool selected = false;

	// Use this for initialization
	void Start () {

	}

	// Update is called once per frame
	void Update () {

	}

	//When object is within interaction range, Do something
        //Turns the object blue
	public void OnLookEnter(){

		//DO THIS
		//sets the color to blue
		GetComponent ().material.color = Color.blue;

		//sets bool to true
		selected = true;
	}

	//When not being looked at, the bool is set to false
	public static void OnLookExit(){

		selected = false;
	}

	//On key press, do something
        //on the press of key 'e', adjusts the height
	void OnGUI(){

		//event e will be the pressing of the e key
		Event e = Event.current;

		//if e = a keyPress, && a characer 'e', && object is in range
		if(e.isKey && e.character == 'e' && selected){

			//uses the objects rigidbody and adjusts it's height.
			GetComponent().AddForce(Vector3.up*100);
		}

	}
}

Game Sample: 9

Hey! Below is the source code to a simple game I created a few years back as a final project for my AP CS class. It’s written in java and was inspired by the game “A Dark Room”, created by Amir Rajan & released in 2013.

Below is some gameplay!

Screen Shot 2018-01-26 at 4.19.48 PMScreen Shot 2018-01-26 at 4.23.17 PMScreen Shot 2018-01-26 at 4.24.31 PM

Very simple but an interesting play! Here is the code:

import java.util.Scanner;
import java.awt.event.*;
public class GameMain
{
 /**
  * Main runs intro sequence and then calls <code> explore </code> method
  */
    public static void main(String []args)
   {
       System.out.println("WELCOME to 9");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println("Instructions: use w,d,s,a and 'Enter' to guide yourself through missions.");
       System.out.println("(Make sure your window fits the entire map) ");
       System.out.println(" ");
       System.out.println("Object guide:");
       System.out.println("1: you");
       System.out.println("2: home");
       System.out.println("3: northern base");
       System.out.println("4: southern wall");
       System.out.println("5: hospital");
       System.out.println("6: market");
       System.out.println("7: motel");
       System.out.println("8: object");
       System.out.println("9: family");
       System.out.println("(type any of these numbers at any time in the game for a quick reminder)");
       System.out.println(" ");
       System.out.println("When you are ready to begin, type 'start'");
       Scanner start = new Scanner(System.in);
       String begin = start.next();
       if(begin.indexOf("start") >= 0)
       {
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
       System.out.println(" ");
           try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
       System.out.println("It's dark here...");
              System.out.println(" ");
       try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
      System.out.println("It wasn't always like this.");
      try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.print("My home...");
           try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("My family...");
     try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     explore();
    }
}
    public static void explore()
   {
    int[][] myArray = {
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  },
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} };  

    int[][] myMapKey = {
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2},
    {2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2},
    {2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,9,2,2,2,2,2,2,2},
    {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2} };
    for(int print1 = 0; print1 < 26; print1++ )
    {
        for(int print2 = 0; print2 < 40; print2++)
        {
            System.out.print(myArray[print1][print2]);
            System.out.print(" ");
        }
        System.out.println(" ");
    }
   System.out.println("energy = 20");
   boolean first = true;
   boolean exploring = true;
   int currentRep = 0;
   int currentCount = 0;
   int energy = 19;
   int progress = 0;
   int clue = 0;
   int food = 5;
   int finish = 0;
    while(first == true)
    {
    int xx = 23;
    int yy = 9;
    myArray = move(xx,yy, myArray);
    mapPrint(myArray, energy, progress);
    energy --;
    first = false;
   }

   while(exploring == true)
   {
       for(int rep = 0; rep < 26; rep ++)
       {
           for(int count = 0; count < 40; count++)            {                if(myArray[rep][count] == 1)                {                    currentRep = rep;                    currentCount = count;                 }             }         }        if(energy > -1 && progress <= 5)       {         myArray = move(currentRep,currentCount, myArray);        mapPrint(myArray, energy, progress);        myArray = significance(currentCount, currentRep, myArray, progress);        energy = energizer(energy, currentCount,currentRep, progress);        progress = progress(progress,currentCount, currentRep);        energy --;               }       if(energy > -1 && progress >= 6 && clue < 20)       {           myArray = advancedMove(currentRep, currentCount, myArray, myMapKey);           mapPrint2(myArray, energy, food);           clue = clue(currentCount, currentRep, myMapKey, clue);           energy = home(energy,currentCount, currentRep);           food = foodSupply(currentCount, currentRep, food);           energy --;         }       if(clue == 20 && finish == 0)       {           myArray = finalMove(currentRep, currentCount, myArray, myMapKey);           mapPrint2(myArray, energy, food);           energy = home(energy,currentCount, currentRep);           food = foodSupply(currentCount, currentRep, food);           finish = family(currentCount, currentRep, finish);           energy --;         }       if(finish == 1)       {           gameFinish();           exploring = false;         }       if(energy == -1)       {           gameOver();           exploring = false;         }       if(food == 0)       {           starve();           exploring = false;         }     } } public static int[][] move(int x, int y, int[][] myNewArray)  {      Scanner input2 = new Scanner(System.in);      String direction = input2.next();      boolean moving = true;      boolean answered = false;      while(moving == true)      {          if(direction.indexOf("w") >= 0 && myNewArray[x-1][y] != 4)
         {
         myNewArray[x][y] = 0;
         myNewArray[x-1][y] = 1;
         answered = true;
         moving = false;
        }
        if(direction.indexOf("d") >= 0 && myNewArray[x][y+1] != 4)
        {
            myNewArray[x][y] = 0;
            myNewArray[x][y+1] = 1;
            answered = true;
            moving = false;
        }
        if(direction.indexOf("s") >= 0 && myNewArray[x+1][y] != 4)
        {
            myNewArray[x][y] = 0;
            myNewArray[x+1][y] = 1;
            answered = true;
            moving = false;
        }
        if(direction.indexOf("a") >= 0 && myNewArray[x][y-1] != 4)
        {
            myNewArray[x][y] = 0;
            myNewArray[x][y-1] = 1;
            answered = true;
            moving = false;
        }
        if(direction.indexOf("1") >= 0)
        {
            System.out.println(" This is you.");
            direction = input2.next();
        }
        if(direction.indexOf("2") >= 0)
        {
            System.out.println(" This is your old home.");
            direction = input2.next();
        }
        if(direction.indexOf("3") >= 0)
        {
            System.out.println(" This is the base to the north.");
            direction = input2.next();
        }
        if(direction.indexOf("4") >= 0)
        {
            System.out.println(" This is a large wall which surrounded the southern base.");
            direction = input2.next();
        }
        if(direction.indexOf("5") >= 0)
        {
            System.out.println(" This is an old hospital. They must have some medical supplies.");
            direction = input2.next();
        }
        if(direction.indexOf("6") >= 0)
        {
            System.out.println(" This is the old market. I'll visit here when my food supply is low.");
            direction = input2.next();
        }
        if(direction.indexOf("7") >= 0)
        {
            System.out.println(" This is an old motel, and my current refuge. Here i can replenish my energy.");
            direction = input2.next();
        }
        if(direction.indexOf("8") >= 0)
        {
            System.out.println(" This is an object. It could possibly help me find them..");
            direction = input2.next();
        }
        if(direction.indexOf("9") >= 0)
        {
            System.out.println(" My Family..");
            direction = input2.next();
        }
        /*if(answered = false)
        *{
        *   System.out.println("Invalid");
        *   direction = input.next();
        *}
        */
    }
     return myNewArray;
    }
public static int[][] mapPrint(int[][]myArray, int energy, int progress)
{
    for(int print1 = 0; print1 < 26; print1++ )
    {
        for(int print2 = 0; print2 < 40; print2++)         {             System.out.print(myArray[print1][print2]);             System.out.print(" ");         }         System.out.println(" ");     }     if(progress >= 1)
    {
        myArray[10][5] = 2;
    }
    if(progress >= 2)
    {
        myArray[4][14] = 3;
    }
    if(progress >= 3)
    {
        myArray[22][20] = 4;
        myArray[22][21] = 4;
        myArray[23][20] = 4;
        myArray[24][20] = 4;
        myArray[25][20] = 4;
        myArray[22][22] = 4;
        myArray[22][23] = 4;
        myArray[22][24] = 4;
        myArray[22][25] = 4;
        myArray[22][26] = 4;
        myArray[22][27] = 4;
        myArray[22][28] = 4;
        myArray[22][29] = 4;
        myArray[22][30] = 4;
        myArray[22][31] = 4;
        myArray[22][31] = 4;
        myArray[22][32] = 4;
        myArray[22][33] = 4;
        myArray[22][34] = 4;
        myArray[22][35] = 4;
        myArray[22][36] = 4;
        myArray[22][37] = 4;
        myArray[22][38] = 4;
        myArray[22][39] = 4;
    }
    if(progress >= 4)
    {
        myArray[14][15] = 5;
    }
    if(progress >= 5)
    {
        myArray[9][34] = 6;
    }
    if(progress >=6)
    {
        myArray[17][10] = 7;
    }
    if(energy >= 4)
    {
        System.out.println("energy = " + energy);
    }
    if(energy < 4)
    {
        System.out.println("ENERGY = " + energy);
    }
    return myArray;
}
public static int[][] significance(int xSpot, int ySpot, int[][] nextLocation, int progress)
{
    if(xSpot == 5 && ySpot == 10 &&  progress == 0)
    {
        System.out.println("I can't believe what this world has come to...");
                   try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
        System.out.println(" ");
        System.out.println("an engraving on the wall reads:");
        System.out.println("'To the north we are safe.'");
                   try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("I must go to the north base");
                     try {
      Thread.sleep(3000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     nextLocation[4][15] = 3;
     System.out.println("Energy replenished");
     System.out.println("(Exit to the North)");
     progress++;
     return nextLocation;
    }
    if(xSpot == 14 && ySpot == 4 && progress == 1)
    {
     System.out.println("More wreckage..");
                           try {
      Thread.sleep(6000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("The North is nothing now.");
     System.out.println(" ");
                        try {
      Thread.sleep(3000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("It makes me wonder of the south...");
                        try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     nextLocation[22][20] = 4;
     System.out.println("Energy upgraded");
     System.out.println("(Exit to the South)");
     progress++;
     return nextLocation;
    }
    if(xSpot == 18 && ySpot == 21 && progress == 2 || xSpot == 19 && ySpot == 22 && progress == 2 || xSpot == 18 && ySpot == 22 && progress == 2)
    {
     System.out.println("It's hard to believe how much has changed..");
                                   try {
      Thread.sleep(6000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("A huge wall seperates me from the far south now..");
                                try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("There used to be a hospital around here.. Maybe they're safe...");
                                try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     nextLocation[14][14] = 5;
     System.out.println("Energy replenished");
     System.out.println("(Exit to the North)");
     progress++;
     return nextLocation;

    }
    if(xSpot == 15 && ySpot == 14 && progress == 3)
    {
        System.out.println("How can I be the only one?");
         try {
      Thread.sleep(6000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("The only..");
      try {
      Thread.sleep(1500);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("Survivor.?");
      try {
      Thread.sleep(5000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("To survive I must find food..");
      try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     nextLocation[9][34] = 6;
     System.out.println("Energy upgraded");
     System.out.println("(Exit to the North)");
     progress++;
     return nextLocation;
    }
    if(xSpot == 33 && ySpot == 9 && progress == 4)
    {
     System.out.println("The world has been brought to nothing..");
     try {
      Thread.sleep(6000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("I can only carry enough food for 5 days..");
     System.out.println("A place to take refuge is necesary.");
      try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     nextLocation[17][10] = 7;
     System.out.println("Energy upgraded");
     System.out.println("(Exit to the South)");
     progress++;
     return nextLocation;
    }
    if(xSpot == 11 && ySpot == 17 && progress == 5)
    {
        System.out.println("This motel will suffice.");
        System.out.println(" ");
         try {
      Thread.sleep(6000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("I am starting to feel the effects of the radiation..");
      try {
      Thread.sleep(3000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("I can only imagine how they feel...");
      try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("My search truly begins here.");
      try {
      Thread.sleep(2000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("This will be my home for now. Here I will rest after each day.");
     System.out.println("But only for now..");
     System.out.println(" ");
      try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("(Find clues (8) in order to find your family");
     System.out.println("All clues are different. Some can only be seen from an angle..");
     System.out.println("Some aren't clues at all.");
     System.out.println("The '8' only represents an area in which a possible clue is near.");
     System.out.println("Therefore, be sure to search the immediate surrounding area as well.");
       try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println(" ");
     System.out.println("As winds speed up, the dust of everything that once was has limited your vision.");
     System.out.println("The '2' now represents explored territory as well as range of vision.)");
       try {
      Thread.sleep(4000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("(Exit to the North)");
     progress++;
     return nextLocation;
    }
    else
    {
     return nextLocation;
    }
}

public static int energizer(int energy,int xSpot, int ySpot, int progress)
{
  if(xSpot == 5 && ySpot == 10)
  {
      return 20;
    }
  if(xSpot == 14 && ySpot == 4 && progress == 1)
  {
      return 25;
    }
  if(xSpot == 19 && ySpot == 22 && progress == 2 || xSpot == 18 && ySpot == 21 && progress == 2 || xSpot == 18 && ySpot == 22 && progress == 2)
  {
      return 25;
    }
  if(xSpot == 15 && ySpot == 14 && progress == 3)
  {
      return 30;
    }
  if(xSpot == 33 && ySpot == 9 && progress == 4)
  {
      return 35;
    }
  if(xSpot == 11 && ySpot == 17 && progress == 5)
  {
      return 40;
    }
    else
    {
        return energy;
    }
}
public static int progress(int progress, int xSpot, int ySpot)
{
    if(xSpot == 5 && ySpot == 10)
    {
        progress++;
    }
    if(xSpot == 14 && ySpot == 4 && progress == 1)
    {
        progress++;
    }
    if(xSpot == 19 && ySpot == 22 && progress == 2 || xSpot == 18 && ySpot == 21 && progress == 2 || xSpot == 18 && ySpot == 22 && progress == 2)
    {
        progress++;
    }
    if(xSpot == 15 && ySpot == 14 && progress == 3)
    {
        progress++;
    }
    if(xSpot == 33 && ySpot == 9 && progress == 4)
    {
        progress++;
    }
    if(xSpot == 11 && ySpot == 17 && progress == 5)
    {
        progress++;
    }
    return progress;
}
public static int[][] mapPrint2(int[][]myArray, int energy, int food)
{
    for(int print1 = 0; print1 < 26; print1++ )
    {
        for(int print2 = 0; print2 < 40; print2++)         {             System.out.print(myArray[print1][print2]);             System.out.print(" ");         }         System.out.println(" ");     }     myArray[10][5] = 2;     myArray[4][14] = 3;     myArray[22][20] = 4;     myArray[22][21] = 4;     myArray[23][20] = 4;     myArray[24][20] = 4;     myArray[25][20] = 4;     myArray[22][22] = 4;     myArray[22][23] = 4;     myArray[22][24] = 4;     myArray[22][25] = 4;     myArray[22][26] = 4;     myArray[22][27] = 4;     myArray[22][28] = 4;     myArray[22][29] = 4;     myArray[22][30] = 4;     myArray[22][31] = 4;     myArray[22][31] = 4;     myArray[22][32] = 4;     myArray[22][33] = 4;     myArray[22][34] = 4;     myArray[22][35] = 4;     myArray[22][36] = 4;     myArray[22][37] = 4;     myArray[22][38] = 4;     myArray[22][39] = 4;     myArray[14][15] = 5;     myArray[9][34] = 6;     myArray[17][10] = 7;       if(energy >= 4)
    {
        System.out.println("energy = " + energy);
    }
    if(energy < 4)     {         System.out.println("ENERGY = " + energy);     }     if(food > 2)
    {
        System.out.println("food supply = " + food + " days");
    }
     if(food <= 2)     {         System.out.println("food supply = " + food + " days");         System.out.println("food supply dangerously low!");     }     return myArray; } public static int[][] advancedMove(int x, int y, int[][] myNewArray, int[][] keyMap) {     Scanner input = new Scanner(System.in);      String direction = input.next();      boolean moving = true;      boolean answered = false;      while(moving == true)      {          if(direction.indexOf("w") >= 0 && myNewArray[x-1][y] != 4)
         {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x-1][y] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x][y+1] == 0)
        {
         myNewArray[x][y+1] = keyMap[x][y+1];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("d") >= 0 && myNewArray[x][y+1] != 4)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x][y+1] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x-1][y];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("s") >= 0 && myNewArray[x+1][y] != 4)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x+1][y] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x][y+1] == 0)
        {
         myNewArray[x][y+1] = keyMap[x][y+1];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("a") >= 0 && myNewArray[x][y-1] != 4)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x][y-1] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x][y+1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x-1][y];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("1") >= 0)
        {
            System.out.println(" This is you.");
            direction = input.next();
        }
        if(direction.indexOf("2") >= 0)
        {
            System.out.println(" This is your old home. This also will represent your vision/ explored territory.");
            direction = input.next();
        }
        if(direction.indexOf("3") >= 0)
        {
            System.out.println(" This is the base to the north.");
            direction = input.next();
        }
        if(direction.indexOf("4") >= 0)
        {
            System.out.println(" This is a large wall which surrounded the southern base.");
            direction = input.next();
        }
        if(direction.indexOf("5") >= 0)
        {
            System.out.println(" This is an old hospital. They must have some medical supplies.");
            direction = input.next();
        }
        if(direction.indexOf("6") >= 0)
        {
            System.out.println(" This is the old market. I'll visit here when my food supply is low.");
            direction = input.next();
        }
        if(direction.indexOf("7") >= 0)
        {
            System.out.println(" This is an old motel, and my current refuge. Here i can replenish my energy.");
            direction = input.next();
        }
        if(direction.indexOf("8") >= 0)
        {
            System.out.println(" This is a clue, necesary for finding them.");
            direction = input.next();
        }
        if(direction.indexOf("9") >= 0)
        {
            System.out.println(" My Family..");
            direction = input.next();
        }

    }
     return myNewArray;
}
public static int[][] finalMove(int x, int y, int[][] myNewArray, int[][] keyMap)
{
    Scanner input = new Scanner(System.in);
     String direction = input.next();
     boolean moving = true;
     boolean answered = false;
     while(moving == true)
     {
         if(direction.indexOf("w") >= 0)
         {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x-1][y] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x][y+1] == 0)
        {
         myNewArray[x][y+1] = keyMap[x][y+1];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("d") >= 0)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x][y+1] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x-1][y];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("s") >= 0)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x+1][y] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x][y+1] == 0)
        {
         myNewArray[x][y+1] = keyMap[x][y+1];
        }
        if(myNewArray[x][y-1] == 0)
        {
         myNewArray[x][y-1] = keyMap[x][y-1];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("a") >= 0)
        {
         myNewArray[x][y] = keyMap[x][y];
         myNewArray[x][y-1] = 1;
         if(myNewArray[x-2][y] == 0)
         {
         myNewArray[x-2][y] = keyMap[x-2][y];
        }
        if(myNewArray[x-3][y] == 0)
        {
          myNewArray[x-3][y] = keyMap[x-3][y];
        }
        if(myNewArray[x-1][y-1] == 0)
        {
         myNewArray[x-1][y-1] = keyMap[x-1][y-1];
        }
        if(myNewArray[x+1][y+1] == 0)
        {
         myNewArray[x+1][y+1] = keyMap[x+1][y+1];
        }
        if(myNewArray[x-1][y+1] == 0)
        {
         myNewArray[x-1][y+1] = keyMap[x-1][y+1];
        }
         if(myNewArray[x+1][y-1] == 0)
        {
         myNewArray[x+1][y-1] = keyMap[x+1][y-1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x][y+1];
        }
        if(myNewArray[x-1][y] == 0)
        {
         myNewArray[x-1][y] = keyMap[x-1][y];
        }
        if(myNewArray[x][y+2] == 0)
        {
         myNewArray[x][y+2] = keyMap[x][y+2];
        }
        if(myNewArray[x][y-2] == 0)
        {
         myNewArray[x][y-2] = keyMap[x][y-2];
        }
        if(myNewArray[x+1][y] == 0)
        {
            myNewArray[x+1][y] = keyMap[x+1][y];
        }
         answered = true;
         moving = false;
        }
        if(direction.indexOf("1") >= 0)
        {
            System.out.println(" This is you.");
            direction = input.next();
        }
        if(direction.indexOf("2") >= 0)
        {
            System.out.println(" This is your old home. This also will represent your vision/ explored territory.");
            direction = input.next();
        }
        if(direction.indexOf("3") >= 0)
        {
            System.out.println(" This is the base to the north.");
            direction = input.next();
        }
        if(direction.indexOf("4") >= 0)
        {
            System.out.println(" This is a large wall which surrounded the southern base.");
            direction = input.next();
        }
        if(direction.indexOf("5") >= 0)
        {
            System.out.println(" This is an old hospital. They must have some medical supplies.");
            direction = input.next();
        }
        if(direction.indexOf("6") >= 0)
        {
            System.out.println(" This is the old market. I'll visit here when my food supply is low.");
            direction = input.next();
        }
        if(direction.indexOf("7") >= 0)
        {
            System.out.println(" This is an old motel, and my current refuge. Here i can replenish my energy.");
            direction = input.next();
        }
        if(direction.indexOf("8") >= 0)
        {
            System.out.println(" This is a clue, necesary for finding them.");
            direction = input.next();
        }
        if(direction.indexOf("9") >= 0)
        {
            System.out.println(" My Family..");
            direction = input.next();
        }

    }
     return myNewArray;
}
public static int clue(int y, int x, int[][] key, int clue)
{

    if(key[x][y] == 8)
    {
        clue++;
        key[x][y] = 0;
    }
        if(clue == 1)
      {
      System.out.println("The remains of some sort of animal.. it makes me sick to my stomach");
      clue++;
     }
     if(clue == 3)
     {
        System.out.println("Death is everywhere..");
        clue++;
     }
     if(clue == 5)
     {
        Scanner input20 = new Scanner(System.in);
        String choice = input20.next();
        System.out.println("A man. He looks so ill..");
        System.out.println("I have a choice to make:");
        System.out.println(" ");
        System.out.println("(a) I give him a day's worth of my food.");
        System.out.println("(b) I leave him to die.");
        System.out.println(" ");
        if(choice.indexOf("a")>=0)
        {
            System.out.println("The man's eyes flutter, and he asks to be left to die.");
        }
        if(choice.indexOf("b")>=0)
        {
            System.out.println("As I'm walking away, the world feels quieter than ever.");
        }
        clue++;
     }
     if(clue == 7)
     {
         System.out.println("Ever since 'the end', these burrows seem to have popped up everywhere.");
         clue++;
        }
     if(clue == 9)
     {
         System.out.println("This bracelet smells exactly like home... It was one of theirs.");
         clue++;
        }
     if(clue == 11)
     {
         System.out.println("A single tree..");
         clue++;
        }
     if(clue == 13)
     {
         System.out.println("Dogs, resorted to their primal instinct. Their meal looks too familiar.");
         clue++;
        }
     if(clue == 15)
     {
         System.out.println("These are her shoes. I'm absolutely sure of it. They're covered in mud.");
         clue++;
        }
     if(clue == 17)
     {
         System.out.println("Blood. It's not theirs. It's not theirs..");
         clue++;
        }
     if(clue == 19)
     {
         System.out.println("A tattered piece of paper. it's addressed to me..");
         System.out.println("'South'. thats all it says. How do i get past the wall. How.");
         finalThoughts();
         clue++;
        }

    return clue;
}
public static int home(int energy, int xSpot, int ySpot)
{
    if(xSpot == 10 && ySpot == 18)
    {
        System.out.println("Home sweet home..");
        System.out.println("(exit to the east or west)");
        energy = 50;
    }
    if(xSpot == 33 && ySpot == 9)
    {
        energy = 50;
    }
    return energy;
}
public static int foodSupply(int xSpot, int ySpot, int food)
{
    if(xSpot == 11 && ySpot == 17 && food > 0)
    {
        food --;
    }
    if(xSpot == 11 && ySpot == 17 && food == 0)
    {
        starve();
    }
    if(xSpot == 33 && ySpot == 9 && food <span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>< 5)
    {
        System.out.println( 5 - food + " more days worth of food. Good.");
        food = 5;
    }
    return food;
}
public static int family(int xSpot, int ySpot, int finish)
{
    if(xSpot == 32 && ySpot == 24)
    {
        finish = 1;
    }
    return finish;
}
public static void finalThoughts()
{
    System.out.println(" ");
    System.out.println("it's so tall...");
    try {
      Thread.sleep(3000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
    System.out.println("But nothing will keep me from them. I know what I must do.");
}
public static void gameOver()
{
    System.out.println("ENERGY = 0");
    System.out.println("GAME OVER");
}
public static void starve()
{
    System.out.println("You lack the necesary food to venture on.");
    System.out.println("GAME OVER");
}
public static void gameFinish()
{
    System.out.print("My");
    try {
      Thread.sleep(1000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.print(".");
     try {
      Thread.sleep(1000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.print(".");
       try {
      Thread.sleep(1000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.print(".");
            try {
      Thread.sleep(3000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("family..");
                 try {
      Thread.sleep(7000);
     } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
     }
     System.out.println("I'm Home.");
}
}

Game Sample: Pig

This is a game which I wrote for a computer science class. 2 of these classes were written by my prof. Adam Smith. He wrote the humanPigPlayer, and theAbstract  pigPlayer.

The game’s rules can be read here.

The class Pig serves as a template for the game to be played within. It keeps track of the scores of each player, and facilitates the play of the game by generating a random number, which represents the die. It also initializes the players. As the code is on this site, the 2 players will be 1 human, and 1 AI which can be viewed below. They are named “Name” and “Name2”

Screen Shot 2018-01-26 at 4.37.01 PMScreen Shot 2018-01-26 at 4.41.21 PM

<pre>
import java.util.Scanner;
/**
 * Skeleton for a pig game
 * @author Aidan Takami
 * @version   1.1
 */

class Pig {
	/**
	 * The score needed to win a round.
	 */
	public static final int WINNING_SCORE = 100;

	public static void main(String[] args) {

		// intro, initialize players
		System.out.println("Welcome to Pig!");
		PigPlayer human = new HumanPigPlayer("Name");
		PigPlayer opponent = new AidansPigPlayer("Name2"); // This is a bot, can also be human.
		int[] roundsWon = new int[2];

		// round 1
		System.out.println("Round 1!");
		if (playRound(human, opponent)) roundsWon[0]++;
		else roundsWon[1]++;

		System.out.println();

		// round 2
		System.out.println("Round 2!");
		if (playRound(opponent, human)) roundsWon[1]++;
		else roundsWon[0]++;

		// report the final results
		reportFinalTally(roundsWon, human, opponent);
	}

	/**
	 * Do one round, crediting the winner.
	 * @param player1 the first player
	 * @param player2 the second player
	 * @return true if player1 won, false if player2
	 */
	// This function does the following:
	// 1. Enter an infinite loop, with player 1 taking a turn, then player 2.
	// 2. Keep track of each player's score and the turn number.
	// 3. When a player wins, print the winner, and break out of the loop.
	// 4. Return
	private static boolean playRound(PigPlayer player1, PigPlayer player2) {
		//declares int values for turn number, player1 score, and player2 score. Also declares a boolean continueOn for loop
		int turn = 0;
		boolean continueOn = true;
		int player1Score = 0;
		int player2Score = 0;

		//loop allows players to play their turn until there is a winner
		while(continueOn == true){

			//adds score from player's turns to their score, and ends loop once WINNING_SCORE is reached
			player1Score += playTurn(player1, turn, player1Score, player2Score);
			if(player1Score >= WINNING_SCORE){
				return true;
			}
			player2Score += playTurn(player2, turn, player2Score, player1Score);
			if(player2Score >= WINNING_SCORE){
				return false;
			}
			turn++;
		}
		return false;
	}

	/**
	 * Play a single turn, returning how many points the player got.
	 * @param player the player whose turn it is
	 * @param turnNum the turn number (0-indexed)
	 * @param score the player's score
	 * @param opponentsScore the player's adversary's score
	 * @return the points that the player won
	 */
	// This function must do the following:
	// 1. Call the player's beginTurn() method.
	// 2. Loop so long as the player wants to continue rolling.
	// 3. Roll a die:
	//     a. If a 1 is rolled, return 0.
	//     b. On any other roll, add it to the pool.
	// 4. If the loop ends, return the pool's value.
	// 5. Be sure to print events frequently, so the human player can see what's
	//    happening!
	private static int playTurn(PigPlayer player, int turnNum, int score, int opponentsScore) {
		//calls beginTurn()
		player.beginTurn(score, opponentsScore);
		System.out.println();

		//declares a boolean for the loop and an int for the die roll
		boolean continueOn = true;
		int dieRoll;
		int rollNumber = 0;

		//sets score for this turn = to 0
		int roundScore = 0;

		//takes input from user before turn starts, but only users. Not ComputerPigPlayer
		if(player instanceof HumanPigPlayer){
		System.out.println(player.getName() + ", when you are ready, type something.");
		Scanner input = new Scanner(System.in);
		input.nextLine();
		}

		//While loop to iterate as long as player wishes to continue on
		while(continueOn == true){

			//rolls a random die value, prints out roll, and returns 0 if a 0 is rolled
			rollNumber++;
			dieRoll = (int )(Math.random() * 6 + 1);
			System.out.println("You rolled a " + dieRoll + "!");
			if(dieRoll == 1){
				System.out.println("Too bad! End of turn!");
				return 0;
			}

			//adds roll to score and prints score
			else{
				roundScore += dieRoll;
				score += dieRoll;
			}
			System.out.println("Your score is now " + score + ".");

			//if score == WinningScore, score is returned. also gives player option to continue or not
			if(score >= WINNING_SCORE || !(player.decideIfShouldRoll(turnNum, rollNumber, roundScore, score, opponentsScore))){

				//ends loop
				continueOn = false;
			}
			System.out.println();
		}
		//returns the score
		return roundScore;
	}

	/**
	 * Deliver a final report, indicating the overall winner after all rounds
	 * have been played.
	 * @param roundsWon an array of <code>int</code>s indicating the number of rounds each player won
	 * @param player1 the first player
	 * @param player2 the second player
	 */
	// This function must do the following:
	// 1. Print out both player's scores.
	// 2. Indicate who the winner was (or if there was a tie).
	private static void reportFinalTally(int[] roundsWon, PigPlayer player1, PigPlayer player2) {
		if(roundsWon[0] > roundsWon[1]){
			System.out.println("Congrats " + player1.getName() + " you won!!");
			System.out.println("The final tally was " + roundsWon[0] + " to " + roundsWon[1] + "!");
		}
		if(roundsWon[1] > roundsWon[0]){
			System.out.println("Congrats " + player2.getName() + " you won!!");
			System.out.println("The final tally was " + roundsWon[1] + " to " + roundsWon[0] + "!");
		}
		if(roundsWon[0] == roundsWon[1]){
			System.out.println("TIE!");
			System.out.println("The final tally was " + roundsWon[0] + " to " + roundsWon[1] + "!");
		}
	}
}
</pre>

This is the base pigPlayer class, created by Adam Smith. AI and the human class both extend this class

<pre>
/**
 * This is the base pig player. Other pig players (e.g. <code>HumanPigPlayer</code>) must
 * extend this class.
 * @author   Adam Smith
 * @version   1.0
 */

abstract public class PigPlayer {
	private String name; // player's name

	/**
	 * The main constructor for <code>PigPlayer</code>.
	 * @param name The <code>PigPlayer</code>'s name
	 */
	public PigPlayer(String name) {
		this.name = name;
	}

	/**
	 * Accessor for the <code>PigPlayer</code>'s name.
	 * @return the <code>PigPlayer</code>'s name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Alert the <code>PigPlayer</code> that its turn is beginning. This method
	 * needs to be implemented in the subclass (even if it is an empty
	 * function).
	 * @param myScore the player's current score
	 * @param opponentsScore the opponent's current score
	 */
	abstract public void beginTurn(int myScore, int opponentsScore);

	/**
	 * Should the <code>PigPlayer</code> roll again? This method needs to be
	 * implemented in the subclass, taking the exact same arguments (even though
	 * some of them may be unused).
	 * @param turnNumber which turn the player is on (0-indexed)
	 * @param rollNumber which roll the player is on (0-indexed)
	 * @param poolSize the number of points currently in the pool
	 * @param myScore the number of points the player has already won
	 * @param opponentsScore the number of points the opponent has already won
	 * @return true to roll again, false to stop
	 */
	abstract public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore);
}
</pre>

This is the human pigPlayer class. Also created by Adam Smith, it allows a human to participate in the game, when initialized in the Pig class.

<pre>
import java.util.Scanner;

/**
 * This is the human pig player. It makes all of its decisions based on input
 * from the keyboard.
 * @author      Adam Smith
 * @version     1.0
 */

public class HumanPigPlayer extends PigPlayer {

	// the shared Scanner among all human pig players (in case there are many)
	static Scanner inputScanner = null;

	/**
	 * The main constructor for <code>HumanPigPlayer</code>.
	 * @param name The <code>HumanPigPlayer</code>'s name
	 */
	public HumanPigPlayer(String name) {
		super(name);

		// if this is the first HumanPigPlayer, allocate the Scanner
		if (inputScanner == null) inputScanner = new Scanner(System.in);
	}

	/**
	 * Alert the human player that his/her turn is beginning.
	 * @param myScore the player's current score
	 * @param opponentsScore the opponent's current score
	 */
	public void beginTurn(int myScore, int opponentsScore) {
		System.out.println(getName() +", it is now your turn!");
		System.out.println("\tYour score is "+myScore+", and your opponent's is " +opponentsScore+".");
	}

	/**
	 * Should the player roll again? This method just asks the human at the
	 * keyboard.
	 * @param turnNumber which turn the player is on (unused)
	 * @param rollNumber which roll the player is on (unused)
	 * @param poolSize the number of points currently in the pool
	 * @param myScore the number of points the player has already won (unused)
	 * @param opponentsScore the number of points the opponent has already won
	 * (unused)
	 * @return true to roll again, false to stop
	 */
	public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore) {
		System.out.println("The pool is now " +poolSize+".");
		return getYesNoQuestion("Do you wish to roll?");
	}

	// private helper function that keeps asking a question until it gets a yes or a no
	private static boolean getYesNoQuestion(String question) {
		while (true) {
			System.out.print(question +" ");
			String answer = inputScanner.nextLine();
			if (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes")) return true;
			if (answer.equalsIgnoreCase("n") || answer.equalsIgnoreCase("no")) return false;
		}
	}

}
</pre>

This is extremely simple AI created by me to serve as an opponent in  a game of Pig.

I simplified resources found here and tried to best optimize the AI’s chance of winning against a human player.

<pre>
/**
 * Pig Player AI which uses resources found online to hopefully best optimize
* the AI's chance of winning.
 * @author      Aidan
 * @version     1.0
 */

public class AidansPigPlayer extends PigPlayer {

	/**
	 * The main constructor for <code>ComputerPigPlayer</code>.
	 * @param name The <code>ComputerPigPlayer</code>'s name
	 */
	public AidansPigPlayer(String name) {
		super(name);
	}

	/**
	 * This function does nothing. It is here to fulfill the requirements of the abstract <code>PigPlayer</code> class.
	 * @param myScore the player's current score (unused)
	 * @param opponentsScore the opponent's current score (unused)
	 */
	@Override
	public void beginTurn(int myScore, int opponentsScore) {
                System.out.println();
		System.out.println("Bot's turn!");
	}
<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>
	/**
	 * Should the player roll again? The computer always rolls once.
	 * @param turnNumber which turn the player is on (unused)
	 * @param rollNumber which roll the player is on
	 * @param poolSize the number of points currently in the pool (unused)
	 * @param myScore the number of points the player has already won (unused)
	 * @param opponentsScore the number of points the opponent has already won
	 * (unused)
	 * @return true to roll again, false to stop
	 */
	@Override
	public boolean decideIfShouldRoll(int turnNumber, int rollNumber, int poolSize, int myScore, int opponentsScore) {
		if(myScore >= opponentsScore + 25){
			if(poolSize < 14){
				return true;
			}
		}
		if (poolSize <span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>< 20) return true;
		else return false;
	}
}

</pre>

Game Sample: Speak Method

This method is a small part of a game I worked on. The purpose of the method is to create a life-like output of words, to mimic dialogue and feel more realistic when characters are communicating.

The method takes a string which is the words to be output, an int which represents, in milliseconds, the pause between each word, and another string, speaker, which is the name of the person speaking.

This method works in a fascinating way and really is able to break down a barrier which is often present in text based games, the lack of realistic interaction.

I am not sure if I will post the entirety of this adventure on my site, but I will continue to update on methods which go into the game.

Screen Shot 2018-01-28 at 11.39.59 AM

<pre>
/*
    Method which creates life like speech by dividing up and outputting single words seperated by intervals
 */

void speak(string statement, int pause, string speaker){
    cout << endl;
    //temp string and stringstream are created
    string temp;
    stringstream ss(statement);
    cout << speaker << ":   ";          //Creates pauses between the output of words     while(ss >> temp){
        std::this_thread::sleep_for(std::chrono::milliseconds(pause));
        cout << temp << " " << flush;
    }
}

</pre>