Showing posts with label miGame. Show all posts
Showing posts with label miGame. Show all posts

Friday, 6 May 2011

C Four, miGame, Part 5

So I was getting a bit frustrated at this AI, I made that I could beat every time... Had a look online at the solution Wikipedia was talking about. This. Shat my pants looking at the amount of information this things goes through. Some guy actually spend 40,000 hours calculating all the possible positions on the board and creating a txt file that holds all these and the transitions between them.

This is tl;dr.

4,531,985,219,092 different possible combinations of moves. That's quite a lot.

So this project seems to be a bit beyond what I was looking to do... I have a pretty average working AI now though. Wont release it just yet though. [Stop timer 201105061934]. Might work on this again later.

Random unrelated image:

I got a job making a website, which is great for University as I need work hours to graduate, but terrible for the guy who hired me because I have NO experience in html or css or php. Should be fun. Will have a play with this blogs design as well. I do quite like it how it is though. We will see.

Will end up something like this:

C Four, miGame, Part 4

Problem Encountered!!!



Something is wrong with the way I am calculating the 'best move'. My plan was to have every winning option score a number of points equal to the number of free spaces on the board.

So let's say it finds a spot where it can win with 3 empty spaces on the board. This spot has a score of 3. In reality the numbers end up much much larger due to the recursion as it finds multiple winning options from the same initial move.



I tried to have an opponent winning make a negative score, as in you don't want to go there. But this ended up with the effect of 'the opponent can win here so I better not block his win'. Stupid...

Tried changing this to increasing the number but then that doesn't work as well as I had hoped either.

Going to get rid of the how many spaces left option and instead will take into account the number of recursive calls to get to this point. I think I'm going to try put the negative thing back in and then have it decide which to choose based on the number furthest from zero (absolute value).

Also had some trouble with stack overflows so have had to limit the number of recursions. At the moment 7 steps in seems enough. Bear in mind that for every step it create another 7 boards. So this gets quite big quite fast.



tl:dr: I have no idea what I am doing at this point and am trying random things until I get something about right.

C Four, miGame, Part 3

Got back from hospital. Turns out the stone was 8mm. But had it blasted and feeling fine now.

I have little to no memory of how to make a C program. Lol...



Because I am using my old code this is going to be a very very poor example of good programming. I've noticed so so many little tweeks I could make. Blarg I haven't even started and I'm disliking C again... Such a tedious language. Luckily the two methods I'm going to use from the old program are set up well enough that I won't need to change anything.



First step: Create a new file for AI code.
From what I can find anywhere it is the same as in Java. Just do it. Examples didn't have 'include' or some other way for it to tell what file it is coming from so that makes things a bit easier. Except every method



Second Step: Allow AI's in the program.
I'm sure there is a much better way to do this but I'm going to hard code in an array of size two with either an h or a c to determine if the player is computer or human. Then add a check in the main loop and if it is a 'c' then call the computer MakeMove method.



Crap it's taken me 30 minutes to get the compiler to work again... Completely forgot everything. Now that I that done I can actually write some code. Woo!



Third Step: Write some code.
Create the AI using recursion to find the best possible move and go there. This is the fun part. Each time the computer is to make a move it will create a copy of the board and make it choose the first column then make the opponent go in the first column and so on and so forth until that column is full, then it moves to the next column and alternatively fills that. As soon as a win is detected the number of empty spaces on the board is the amount of points that win is worth. Then it starts again but places the its first move in the second column and then opponent in the first and it in the first. And so on and so on. This sounds like terrible way to do this. But computers are fast.To those that do program I'm going to be using recursion and so this SHOULD involve minimal code on my part. Which is the plan.

Going to start this now. [Start timer] 201105061147
[Pause timer] 201105061316
[Back again] 201105061650

Tuesday, 8 March 2011

miTanks, Part 10

It's not working... I've been trying different ways to get the game to draw to screen though I just don't have it working yet. Fixed a couple minor bugs, as I hadn't moved everything across from the PC version.

When running I follow the debug and step through the program. Turns out the game runs perfectly, that is the game constructs and plays out completely with two random computer players, except it never draws to the screen. Thought the onDraw(Canvas canvas) method would be called automatically every couple of milliseconds. Turns out no. So, I need a way to get the canvas (i.e. the screen) so that I can call the method myself. Working on it...

If anyone knows how android views work, let me know...

As for sounds, I have this site that generates old school game noises. So I'll probably use that for my sounds. Means I don't have to search for people to make decent sounds. Lol. Sorry to those of you that did help with that. There just weren't enough to continue with them.

So the site looks like this:



Here is the link. Will probably be my one stop shop for sounds in the future. Check it out.

My roommate made me a little icon for the game as well. His tanks looks better than the little ones I made in the last post. So may end up replacing them with copies of his. I'll post the icon when I have my computer again.

Cheers,
Milk

Saturday, 5 March 2011

miTanks, Part 9

That's right! miTanks is back. After a very very long break I've got motivated to finish it. Or at least get it on the platform it was originally for. Haven't really had much commitment from Foo, which is both our faults really. I'm not the best teacher and he has little / no coding experience. And lobbing him with graphics was not the best move.

Sorry to everyone that doesn't have an Android, but you can still enjoy my struggle with xml and the Android graphics classes... And the PC version will still have the same look and feel as the Android version, with the obvious touch-screen exception.

Can't remember if I've said already or not but this is a fantastic, simple example of how to make a game on Android. The game is open source so I'm basing the majority of figuring out how to do graphics on this. For those of you know don't know software programming is basically: "Learn the basics; google the rest."


Image courtesy of xkcd.

I think I have a pretty good idea of what I need to do now. The tanks are going to look something like this:
 

And the turrets are just going to be a black smooth edged square, pointing at whatever angle they need to. The ground is either going to be a solid colour or each pixel will be 1 of three colours. This will depend on how much time it takes up to search and utilise a very very large 2D colour array.

I'll be using the sky square (not a box, it's 2D) Foo created earlier, because it is awesome. This will be the background of most of the levels. Might end up overlaying some objects like a building or something.




What else? Damage isn't quite right. The tank only takes damage if the very centre is hit. Not a major flaw but not very ascetically pleasing.

I'll get to work on this all tonight and post something on Monday(?) about what I have done.

Links to the other miTanks posts:
Part 1, The Plan
Part 2, Initial Concept
Part 3, Object Oriented Design + Update
Part 4, Sound Request + Update
Part 5, First Screenshots
Part 6, Ground Types
Part 7, Weapons + Ground Dynamics
Part 8, Initial Release

The last one contains the initial release for PC. Have a look at that if you haven't already. Just renamed all my posts... I had two part 4's AND 2 part 6's. That's just bad...

And as always suggestions are always appreciated.

Cheers,
Milk

Tuesday, 22 February 2011

miAlchemy

So Foo showed me this free game on Android called Alchemy. It's pretty simple. You start off with the four basic elements; earth, fire, water, and air. Then you drag one on another and make something else. e.g. earth + water = swamp, fire + air = energy, energy + swamp = life. There are 360 elements to unlock in the free version.



Being a coder I thought that it seemed pretty simple to make. So, I made miAlchemy (original, I know). Now it doesn't look as awesome as the Android one, and it's for computer instead. It's written in Python; like the last few projects I've put up here.



The way it figures out which elements exist allows for drop in add-ons. That way you can simply add a file into the elements folder and BAM! it's in the game. Images can be changed just as easily.

Mine also allows more then 2 things to be combined at a time. So something like: earth + air + fire + water = life, is possible.

My version has:
Earth
Air
Water
Fire
Alcohol

Put some suggestions in the comments and I'll add it to the game. If it's not obvious, let me know how to make it.

When I get some more elements into the game I'll package it up and release it for you guys.
If you want to do some 40x40 images would be good too.

Tuesday, 18 January 2011

C Four, Connect Four, miGame

I'm taking a break from miTanks for a while. Here's one of my first ever programs.

I spend alot of my time in lectures at University playing Connect Four on a piece of paper against friends. This is the best paper game we could come up with. Turn based, so could simply pass notes or signal which column to drop in. And there was no need for an eraser; imaging trying to play chess with a pen.

At the time we were learning C programming and had to come up with some simple program to prove we learnt something in the course. Alot of people went with a Facebook similar 'What animal are you?' kind of game. Boring!



It took about 2-3 hours. Remember this was my first C program I created purely by myself, aside from Visual Basic and MicroWorlds (if that even counts).

Code:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
//C(onnect) Four
//Created by: Milk
//Date of final build: 19/10/09
//Height of each line
#define LINE_HEIGHT 6
#define LINE_WIDTH 7
void DrawBoard(int grid[LINE_HEIGHT][LINE_WIDTH]);
int CalculateWin(int grid[LINE_HEIGHT][LINE_WIDTH], int player);
int ValidInput(int input, int grid[LINE_HEIGHT][LINE_WIDTH]);
int main(void)
{
 //Plays connect four
 int grid[LINE_HEIGHT][LINE_WIDTH] = {0};
 int gameOver = 0;
 int input = 0;
 int player = 1;
 char inputValid;
 int i;

 //Draw the intitial board (empty)
 DrawBoard(grid);
 while (gameOver == 0 && (grid[LINE_HEIGHT - 1][0] == 0 || grid[LINE_HEIGHT - 1][1] == 0 || grid[LINE_HEIGHT - 1][2] == 0 || grid[LINE_HEIGHT - 1][3] == 0 || grid[LINE_HEIGHT - 1][4] == 0 || grid[LINE_HEIGHT - 1][5] == 0 || grid[LINE_HEIGHT - 1][6] == 0)) {
  //Get input from user
  input = 0;
  printf("\nWhere would you like to go, player %d?\n", player);
  scanf("%d", &input);
  //Decide if input is a valid move
  inputValid = ValidInput(input, grid);
  //If input is not valid prompt for a valid move
  while (inputValid == 0) {
   printf("Please choose a valid position: ");
   scanf("%d", &input);
   inputValid = ValidInput(input, grid);
  }
  //Add input to grid
  for (i = 0; i < LINE_WIDTH; i++) {
   if (grid[i][input - 1] == 0) {
    grid[i][input - 1] = player;
    break;
   }
  }
  //Draw the board
  DrawBoard(grid);
  //Calculate if there is a win
  gameOver = CalculateWin(grid, player);
  //Set the next players turn
  if (player == 1) {
   player = 2;
  } else {
   player = 1;
  }
 }
 //Print winner
 if (gameOver == 0) {
  printf("\n\nThere are no more available moves!\nIt's a draw\n");
 } else {
  printf("\n\nCongratulations player %d!\nYou won\n", gameOver);
 }
 return 0;
}
void DrawBoard(int grid[LINE_HEIGHT][LINE_WIDTH])
{
 //Draws the board
 int i, j;
 printf("\n\n\n\n\n");
 for (i = LINE_HEIGHT - 1; i >= 0; i--) {
  printf("\nI");
  for (j = 0; j < LINE_WIDTH; j++) {
   if (grid[i][j] == 0) {
    printf("   I");
   } else if (grid[i][j] == 1) {
    printf(" X I");
   } else {
    printf(" O I");
   }
  }
 }
 printf("\n__1___2___3___4___5___6___7__");
 return;
}
int ValidInput(int input, int grid[LINE_HEIGHT][LINE_WIDTH])
{
 //Calculate if input is valid
 if (input < 0 || input > 8 || grid[LINE_HEIGHT - 1][input - 1] != 0) {
  return 0;
 } else {
  return 1;
 }
}
int CalculateWin(int grid[LINE_HEIGHT][LINE_WIDTH], int player)
{
 int i, j;
 //Calculate if there is a win on the horizontal
 for (j = 0; j < LINE_WIDTH - 3; j++) {
  for (i = 0; i < LINE_HEIGHT; i++) {
   if (grid[i][j] == grid[i][j + 1] && grid[i][j] == grid[i][j + 2] && grid[i][j] == grid[i][j + 3] && grid[i][j] != 0) {
    return player;
   }
  }
 }
 //Calculate if there is a vertical win
 for (i = 0; i < LINE_HEIGHT - 3; i++) {
  for (j = 0; j < LINE_WIDTH; j++) {
   if (grid[i][j] == grid[i + 1][j] && grid[i][j] == grid[i + 2][j] && grid[i][j] == grid[i + 3][j] && grid[i][j] != 0) {
    return player;
   }
  }
 }
 //Calculate if there is a diagonal up-right win
 for (i = 0; i < LINE_HEIGHT - 3; i++) {
  for (j = 0; j < LINE_WIDTH - 3; j++) {
   if (grid[i][j] == grid[i + 1][j + 1] && grid[i][j] == grid[i + 2][j + 2] && grid[i][j] == grid[i + 3][j + 3] && grid[i][j] != 0) {
    return player;
   }
  }
 }
 //Calculate if there is a diagonal up-left win
 for (i = 0; i < LINE_HEIGHT - 3; i++) {
  for (j = LINE_WIDTH - 1; j >= 0; j--) {
   if (grid[i][j] == grid[i + 1][j - 1] && grid[i][j] == grid[i + 2][j - 2] && grid[i][j] == grid[i + 3][j - 3] && grid[i][j] != 0) {
    return player;
   }
  }
 }
 //No win
 return 0;
}


When compiled the exe file is only 56.0KiB. So it's pretty much always on my USB drive now.
And here it is:
http://rapidshare.com/files/443141503/Connect4.txt
I don't think rapidshare likes exe files so once you download just change the file extension (txt) to exe, and it will work. Give it a go.

Looking back at this code there is not actually too many things I would do differently. Would've been a nice OO exercise though.

If anyone wants to give me a game just tell me your starting move. Let's play. Lol

Cheers,
Milk

Friday, 31 December 2010

miTanks, Part 2

Something I've missed:
Android apps are written in Java plus some xml for view layouts etc.

I have started drawing up a rough class diagram for the game and started to think about how to implement destructible terrain. As we want a clean fall animation for the ground when a piece is broken below, I am currently thinking about having the entire game screen as a 3d boolean array. Animations with this will be incredably easy. Hopefully this won't be too much to process every turn.

Some minor code has been written to help visualise the working of the tank class. As this is early on in the process it is likely to be rearranged quite regularly, due to the nature of eXtreme Programming.

I will try to have the game run on both the Android and a computer. This will help for initial game development as testing on the Android Virtual Device is time consuming. Also when the game is complete I will release a run-able jar file so everyone on here can play the game.

Most likely won't be doing small releases as we go, due to the size of the app. When it is actually playable it will almost be finished. Just bug fixes, extra weapons and smoothing out code after the app works.

Here are some initial concept shots by Foo.
Initial Concept Screenshot
Second Concept Screenshot


Sky

Tree

Concept Tank 1

Sunday, 26 December 2010

LetterBloxHack

Situation:
So I found this awesome Robot class in Java that allows you to easily tell the computer where to click or what buttons to press on the keyboard etc. Sounds awesome right? I thought so. At the time I played a lot of games over at http://www.omgpop.com/. If anyone is familiar with LetterBlox, it's basically boggle. They give you some letters and from those letters you have to create words. Words are worth some value of points depending on rarity and size. The highest points win.

tl;dr Plays letterblox for you.

Solution:
This is part of the miGamer package I am working on. As we were having tournaments at university for who can play this game the best, and because it is easier, I went with another GIUless application. For this to work you must edit the code. As I am doing software engineering, having Eclipse open in the background was the norm. This allowed me to edit and run my program quickly and easily.

Notes:
  1. To prevent an outright win, I have not perfected the program. That is it won't do every single combination.
  2. Due to computer system restrictions and to prevent overloading the site, at most 10 combinations are attempted in a second.
  3. To use the application you must change the char[] letters = {'F', 'A', 'D', 'R', 'T', 'S'}; to the letters produced for each round.
  4. The application has a short delay before it starts to type the 'words' in. During this delay you should alt-Tab back to the game and click on the game. Otherwise you will see text typed into whatever is currently open.
  5. Due to the game being clever I have allowed the application to attempt typing multiples of the same letter, even if there is only one. This will simply leave off the last occurrences. This causes some of the problems with missing some words, see note 1 for why this has not been fixed.
  6. Again to due problems with typing when the game is over, this once caused my account to be disabled and ip suspended on the site, the application terminates after 60 seconds regardless of how far it has actually gotten to all attempts.
  7. A suggestion I have had is rather than typing hundreds of incorrect or repeated answers, is to store a dictionary of words and use a look up to see if the word exists before typing. This, however, would cause the program to run a lot slower and finding the same dictionary used by the game would also be very difficult.
  8. Again this code uses very little object oriented design ans so had I known how to do this in C, I would have.
The solution is in no way a perfect solution to the play the game. Although while using the application I have not lost a single match and so I believe it to be effective enough for the purpose it is built.

Code:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class LetterBloxHack extends Robot implements ActionListener{
 // The timer allows a combination to be created every .1 seconds
 private final Timer TIMER;
 // The counter allows the timer to be stopped after 1 minute
 private long counter = 0;
 // An array of the letters
 private int[] LETTERS;
 // An array of the order of the letters
 private int[] press;
 // The current length of word
 private int size = 1;

 /**
  * Creates the LetterBloxHack object and begins after .5 seconds
  * @param letters the letters to be sorted
  * @throws AWTException
  * @throws InterruptedException
  */
 private LetterBloxHack(char[] letters) throws AWTException, InterruptedException {
  super();
  // Sets the timer with a 50 millisecond delay
  TIMER = new Timer(0, this);
  // Initialises the LETTERS field
  this.LETTERS = new int[letters.length];
  for (int i = 0; i < letters.length; i++){
   this.LETTERS[i] = letters[i];
  }
  // Initialises the press field
  press = new int[letters.length];
  for (int i : press){
   i = 0;
  }
  press[0]--;
  // Short pause
  Thread.sleep(500);
  // Begins the timer
  TIMER.start();
 }

 /**
  * Starts the program.
  * The letters to be sorted are inputed here by the user.
  * @param args
  * @throws AWTException
  * @throws InterruptedException
  */
 public static void main(String[] args) throws AWTException, InterruptedException {
  char[] letters = {'F', 'A', 'D', 'R', 'T', 'S'};
  LetterBloxHack hack = new LetterBloxHack(letters);
 }
 /**
  * Performs a sort every .1 seconds
  */
 public void actionPerformed(ActionEvent arg0) {
  // Increments the counter to stop after 1800 computations
  counter++;
  if (counter > 1800){
   TIMER.stop();
  }

  // Increment the first pointer
  press[0]++;

  try{
   for (int i = 0; i < size; i++){
    // Checks if a pointer is above the maximum
    if (press[i] >= LETTERS.length){
     press[i] = 0;
     press[i + 1]++;
     if (size == (i + 1)){
      size = (i + 2);
      for (int j = 0; j < size; j++){
       press[j] = 0;
      }
     }
    }
   }

   //  Types the characters
   for (int i = 0; i < size; i++){
    keyPress(LETTERS[press[i]]);
    keyRelease(LETTERS[press[i]]);
   }
   //  Types an enter
   keyPress(10);
   keyRelease(10);
  } catch (ArrayIndexOutOfBoundsException e){
   //  Catches an exception that will represent the end of the sorting
   TIMER.stop();
  }
 }

}