Automated Job Pipeline

Ultimately automation should trigger on changes in the code repository.
To that end I need a GitHub Webhook to trigger the pipeline.

The entpoint that get the trigger could be either a server that I am running or a service that AWS provides.

If I run my own service I would need to keep that online on my own cost.
Running a t2.nano on AWS costs 60$ per year – really cheap – not cheap enough.

So the next thing I looked into were AWS Code Pipelines. The trigger reaches AWS and I do not need to run anything. After that the code pipeline executed for a few minutes and quits again. So the costs are so low I could not even put a number on it.

Setting up CI / CD was very simple. Effectively AWS automatically connects with the repo and sets up the hooks for you – all you need is to authorize AWS to connect to the Github API in your name.

Since I want to pull my gcc compiler from hub.docker.com I ran into an Issue where docker just would not want to run on the Pipeline Machine. It turns out there are a few configuration options hidden in the Environment section of the Code Pipeline configuration.

Image Override reveals the option to upgrade the pipeline.
I needed:

  • aws/codebuild/standard 2.0
  • Check Priviledged

Checking both these options made my pipeline run and complete successfully.


version: 0.2
phases:
install:
runtime-versions:
docker: 18
pre_build:
commands:
- docker pull gcc
build:
commands:
- docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp gcc make
artifacts:
files:
- ./main

The output artifacs ended up in an S3 bucket

If you just want to hang out you may have a chance to catch me on  twitch .
Get in touch on twitter

Here are all the links I ended up inspecting for this:

S3 Caculator
Amazon CI/CD Practices
Expedia’s Automated CI/CD
How to Deploy a Jenkins Cluster on AWS in a Fully Automated CI/CD Platform
Save up to 90% on CI/CD
Accelerating DevOps Pipelines with AWS
/var/run/docker.sock
Setting up a CICD Pipeline for Containers on AWS
CodePipeline User Guide
CodePipeline Pipeline Structure Reference
How to apply CI/CD by using GitHub, CodeBuild, CodePipeline and ECS
Amazon ECR Sample for CodeBuild
Troubleshooting CodeBuild
Build Specification Reference for CodeBuild
Runtime version selection is not supported by this build image
Change a Build Project’s Settings in CodeBuild
How to run docker-compose on AWS CodeBuild?

Development on a Cloud machine

After a quick preliminary search I found that I could use Visual Studio Code locally and automate everything through the task concept that Visual Studio Code utilizes. I switched to AWS Cloud 9 and that clicked for me in a way that maybe I could have gotten from Visual Studio Code as well with more experience.

Over all I am pretty satisfied with both approaches and I selected AWS Cloud 9 for now. I think working with the IDE for a bit will show me a few more strengths and customization options.

Let me run through some of the common elements that I used when setting up both solutions.

Installation

Installation in both cases is a simple task where direct support is available and ample, both require launching a virtual machine with AWS Cloud 9 that machine is actually installed in one go with everything else. For the regular EC2 instance I need to manage my pem certificate myself, with the AWS Cloud 9 solution that is automagically done with my login.

Visual Studio Code requires an extension to use the EC2 instance as its filesystem. That extension is conveniently called SSH FS.

The SSH FS configuration for my EC2 instance looked like this:

"sshfs.configs": [ {
"name": "Aypahyo_EC2",
"root": "~/",
"host": "ec2-18-194-10-20.eu-central-1.compute.amazonaws.com",
"port": 22,
"username": "ec2-user",
"privateKeyPath": "C:/AWS/AWS_Aypahyo_DevMachine.pem",
}]

In retrospect it may be useful to mount one filesystem per project since the root folder of the workspace matters.

Code and Compile

I wrote a simple C++ program with a makefile for both options. Visual Studio Code makes you download an extension for C++ as a basis for all tasks, In AWS Cloud 9 languages are preinstalled and can compile out of the box. I disliked that Cloud9 does that, I could not tell what compiler options were used nor which compiler was at play.
In both versions it is possible to define your own runners or tasks respectively and that is what I ended up doing.

To compile and run I created an sh script on the server side that uses docker compile to compile my makefile project. Docker was properly installed on the AWS Cloud9 machine, somehow I had to install it on my EC2 instance that I used for Visual Studio Code.

docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp gcc make

Compiling using docker means that your output is on the console so it needs to be parsed in order to tell if an error happened. I was able to set that up in Visual Studio Code and very conveniently the relevant files for that end up in the repository meaning that they would be shared with future me on another machine. the error report showed up in the error log and was clickable – however visual studio code could not find the correct file based on the reported filename. I could not tell why and I assume it is some conflict with the SSH FS plugin. In Cloud 9 I could not find any form of error window and was unable to configer that.
With both solutions I am not sure how debugging would be integrated with my docker compile choice.

Source Control

When it came to git integration Visual Studio Code just did not show GIT as an option although everything comes pre installed with that package. My assumption here is that it would show if visual studio code would detect the .git folder on my system. Since the connection to my files ran through the extension SSH FS I assume Visual Studio Code could not prosperly inspect the files on the remote machine. In that sense git behaved just the same with both machines where the git commands had to be entered on an ssh terminal. The only difference here is that the SSH terminal connection had to be set up on my machine for the visual studio code solution to work where as in the AWS Cloud 9 solution the connection is part of the package and a terminal is a right click away.

Copy a File

Getting files to the remote machine was simple using Visual Studio Code because I could just copy them in the IDE. In AWS Cloud 9 getting files to the machine requires opening a dialog that has a drop box where you can copy files to and they would be uploaded.

A note on permissions

File permissions had to be changed not only for execution of the shell script (chmod +x) but also on the key files so ssh would accept them. This is simple on linux (chmod 600) and very complicated on windows.

Get in touch.

If you have a hint be sure to contact me on  twitter .

If you just want to hang out you may have a chance to catch me on  twitch .

Bibliography, sort of…

missing separator
Git Tips
Cloud 9 Experimental
Cloud 9 Full Stack Part 1
Chmod permission explained
Introduction to AWS Cloud9
Code Cloud IDE Crash Course
No source control providers registered
error permission denied publickey
Github Network Ports
Install Git EC2
Setup EC2
Setup EC2
Terminal will be reused
Create sh on windos, run on linux
Using Visual Studio Code To Develop With Containers
Setup EC2
vs code c development with containers
is-there-a-way-to-refresh-the-task-list-in-vscode
Visual Studio Code inserts spaces when editing a Makefile
gcc on docker
C++ development with Docker containers in Visual Studio Code
Got permission denied while trying to connect…
Get Started
Running Docker on AWS EC2
How to connect Visual Studio Code to remote server – Fixed
marketplace Kelvin.vscode-sshfs
SSH: Permission denied (publickey)
Windows SSH: Permissions for ‘private-key’ are too open
Develop on a Cloud Machine
Developing for the Cloud in the Cloud.
Using EC2 instance as main development platform
AWS Toolkit for Visual Studio Code
Editing files in your Linux Virtual Machine made a lot easier with Remote VSCode
Remote Pair Programming Made Easy with VSCode Live Share
Connect to your remote Linux computer
Remote Editing with VS Code
SSH FS
C/C++ for Visual Studio Code (Preview)
Integrate with External Tools via Tasks
C++ development with Docker containers in Visual Studio Code

Overview #dk30-spring-2019

I am taking part in #dk30-spring-2019 which you can find here.

The Project is structured into 4 Weeks. MY output should be thirteen blog posts and an interactable cloud thing.
In order to get a clean front page I am creating this post so I can collect my links while I move the project forward.

Week 1:
I am a proud owner of an AWS evaluation account which will last for a year.
Thinking about what may come in handy in week 4 and what I want to accomplish I think what I need will contain:

  • Hosting a remote machine for actual development in the cloud.
  • Hosting a CI / CD container that automates josb.
  • Hosting a package repository to store my artifacts
  • Integrating CI CD with artifact storage
  • Hosting orchestration
  • Scaling orchestration
  • Integrating CI CD with orchestration
  • Using a webservice for authentication
  • Running a db container
  • regular db backups and recovery
  • service replication for geo locations
  • client side computation
  • twitter integration

Looking at that list makes me feel a bit squeamy since I know those topics a bit and I am not sure If I have enough pare time to pull this off in a month.
Never give up, never surrender :)

Find me on twitter or twitch for comments.

WEEK 1 GOAL
Make a list of thirteen Tutorials that represent individual technologies. Complete three Tutorials. Publish three summaries

WEEK 2 GOAL
Complete five Tutorials. Publish five summaries

WEEK 3 GOAL
Complete five Tutorials. Publish five summaries

WEEK 4 GOAL
Find an interconnected example that uses some technologies in a connected way. Create a tutorial for that example. Publish that tutorial.

TicTacToe – V003

The state of Version 003
model of the tictactoe programming project

In Version 3 I included an AI-Player and added three more game modes. The computer player has its own set of tests to ensure its function.

The AI is essentially asleep until the game state changes.
A changed game state triggers the AI and it checks, if an AI move is expected.
The AI is keeping a list of the Tic Tac Toe fields and tries to occupy them at random.
It keeps trying to occupy fields until the game no longer looks like the AI should move.

Encounters while implementing the feature
The players depend on the game, so in order to make testing easier the interface IGame (see picture above) was extracted.
The framework Rhino Mocks is easiest to use with Interfaces.

A great advantage of a testproject is, that a whole proof of concept can be integrated entirely within the testproject.
This is not listed in the overview, since it does not belong to the gametests. But I had a problem raising events using Rhino Mocks.
To solve this issue I created a stand alone selftesting small example which worked fine.
Since this will not influence the project in any way I can just let this small example stay there forever.
If Rhino Mocks ever changes their behaviour I will be notified by the failing test.

While testing the AI manually, I discovered a bug, which was created during the transition from V001 to V002.
A feature was not ensured by testing so a simple change created a bug that was not immediately spotted.
This demonstrates the importance of testing even in one person projects.

Next To Do
After getting some features done it is wise to spend some time refactoring before implementing the next feature.
Looking at IGame it seems like most of the stuff is made to give information in what state the game is currently in.
The concept of the gamestate is also visible in the way the computer player tries to infere (see private makemove in the sourcefiles) if it is its turn.
And a third indicator is that the gamestate is even a named concept in the viewmodel.
We will create a gamestate that answers the questions about the gamestate that the other colaborators have.

Map tiles that are not taken by a player bare the char(32) (= spacebar character) marking.
I think they should be taken by ‘NoPlayer’ – so we have to implement an IPlayer interface for NoPlayer and use that instead of char(32).

The feature that we will implement after those refactorings is a sligthly harder AI that actually thinks before making a move.

You can Download the sourcecode here.

TicTacToe – V002

Where do we want to be?

The featurelist of the game we want to have contains several AIs, selectable tokens and four gamemodes. The idea is to see what impact those requirements have on our architecture.

Where did we start?

We started with a single God Object, no testing and no style control. Adding those cleaned up the god object, revealed some bugs and enabled easy refactorings. We are now in a state where the architecture is quite ugly but we can safely change the code in a reasonable time.

Where are we now?

model of the tictactoe programming project

The current state is V002. It features some refactorings towards our next feature but nothing major. It consists of three Projects, each serving a specific role. The GUI project contains all GUI relevant coding including the adaption to the game. The game project contains all game logic that can be seperated from the GUI. Last but most improtant is the testing project, featuring all tests that verify the game is working as intended. In its current version it acts on the gui just like the user would and controls the result.

What will we do next?

We will implement an easy AI so we can have fun playing against it and also because it is a step towards our final goal. In an easy game like this there is basically no need for the AI to cheat (I personally like games where the AI does not cheat ). That means that we can create an AI that uses the game just like a human would use the game. To make it easier we will route all userinteraction throug an interface ( IPlayer ) and make the human a concrete implementation of that interface. Once that is complete it will be quite easy to create an AI that randomly clicks buttins until the game is over.

TicTacToe StyleCop

As mentioned in an earlier post I wanted to try out FXCop. The first thing always to do is to read the Wikipedia article about the topic.

I learned that there is another option called StyleCop. It seems to be easier to adapt to a projects custom rules. This might come in handy, if something goes wrong. So I use StyleCop instead of FXCop.

The first step now is to enlist another target in the buildtool, so that StyleCop gets executed automatically with the same button push as all other tools. Fortunately it is already prepared and all that has to be done is to load the target after the CSharp targets were loaded. The sequence may be important because StyleCop will overwrite (or append itself to) a targets dependencies. It is easy to find a tutorial on the web. Further down is a snippet of what I wrote into the project file.

On compiling it immediately showed 266 warnings but executed anyway. And since the only good rules are enforced rules, I tried to set the project to treat all warnings as errors. This did not achieve the result wanted, it seems that a different set of warnings is referenced by that entry. If you know all about this behaviour please comment below. Fortunately StyleCop has an option to treat warnings like errors. The option is listed in the example below. Beware of linebreaks, they can interfere with parsing the keyword “false” and lead to an error on triggering the buildtarget. Notice I did not use the placeholder for the program files directory. This somehow results in my Windows resolving that to a different directory. I am quite in the dark why that happens, it may be endemic to my machine.

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="C:\Program Files (x86)\MSBuild\StyleCop\v4.7\StyleCop.targets" />
<PropertyGroup>
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
</PropertyGroup>

StyleCop was quite picky about getting the comments right. I see some use for that in a company. For example having copyright headers in each file may be a good idea. Also interesting is enforcing comments on external methods and classes, so that the customer of an assembly knows how it is supposed to be used. In most of the cases I think commenting is bad style. Comments that mark sections usually can be formulated as a methodname containing that section. Comments explaining code usually only serve as a monument of a programmer giving up on the attempt to write a codeportion easy to read. Comments explaining a set of lines or a calculation are a DRY violation – information was written twice. Comments that exclude lines of code are overcautious, repositories save versions and filedeletion is not murder. Having said that – if there is no way of reminding future me how it all works – I will not hesitate to write a comment regardless of style.

I ended up removing all documentation rules. It was amazingly straight forward. Just find the Settings.StyleCop file on your system and doubleclick it. If the installer did his job a specialized GUI will open and allow you to disable or enable any rules. On my system the file was located in "C:\Program Files (x86)\StyleCop 4.7"

The remaining 201 errors were minor things like naming conventions that are underestimated by a lot of programmers I know. If a whole company agrees on one set of style rules and enforces them, using a static codeanalysis tool makes it easier for everyone in that company to read the code.

I just feel better having a styleguard who watches my code, alerts me and stops compilations as long as I don’t adress the style problems. Comment about your experience with enforced style rules.

The next steps will be to slowly add the initial features and illustrate how design patterns can help with the features, I initially wanted TicTacToe to have.

TicTacToe Tested

I recently got married and had a lot of other stuff do do as well. My apologies for not releasing a new post in a while.

Now I did not get around to try out FX Cop so that remains on my todo list. But I added some unit tests to my project.

I coded the TicTacToe the dirty way without test in my first iteration. There are a couple of downsides to it – the worst being that you release untested code to your customer – basically telling your customer that you did not ensure that you actually did the job he asked you to do.

I write this because during introducing tests I noticed a quite sever programming bug. The rules that check if a win condition was triggered had an error. Manual testing did not reveal it because manual testing is not as extensive as automated testing. I was able to discover the error in a test that screened my TicTacToe for all clickable combinations – something I would never do by hand.

All clickable combinations in Tic Tac Toe are 255168. This number can vary, depending on your definition of how unique a combination has to be. I pulled my test numbers from an article on the web. If you generate all clickable combinations and use them to automatically play the game you should get:

  • 0 games ending in zero, one, two, three and four moves.
  • 1440 games ending with a winner in 5 moves.
  • 6 moves -> 5328 games
  • 7 moves -> 47952 games
  • 8 moves -> 72576 games
  • 9 moves -> 81792 games and
  • a draw result for 4868 games.

Using this data you can create a test that tests all combinations and reveals all coding errors in the win condition code.

Before you can actually use NUnit as a test framework to implement the tests, there are a couple of things you have to do first.

  1. Get NUnit
  2. Create a new project that will contain your tests
  3. Link to
    • the project you want to test
    • the NUnit framework (NUnit-???\bin\nunit.framework.dll)
    • the NUnit GUI (NUnit-???\bin\lib\nunit-gui-runner.dll)
    • the Rhino framework (NUnit-???\bin\lib\Rhino.Mocks.dll)
  4. Switch your project target framework to “Framework 4″ – required for Rhino Mocks
  5. Edit the assembly of the project under test and tell it to allow your test project to view internals
  6. Create your main method to launch NUnit using the debugger.

I guess that a lot of the above steps are unclear to most, so I will elaborate a bit.

Getting NUnit should not be a problem – you basically download it and unzip it. You will now face the choice of putting it into your program directory making developement easier and more portable, or putting it outside of your project making it easier to reuse for other projects. The choice is yours.

Create a new project: See to it, that it is in the same folder as the production code and keep it in the same solution folder so you can switch between them easily. The NUnit GUI is a windows forms application as far as I can tell. To ensure that all the required assemblies are already linked, you want to start this project as a forms application. You will want to delete the initial empty form since there is no point in keeping it.

Link all the dependencies: If you started the project not as a forms application you have to link those too. Otherwise you just need to link the things listed above. Initially you will not need the Rhino framework. It is a mocking framework that is quite easy to use and it comes with NUnit. I’ve never written meaningful code without wanting to mock something during testing, so you might as well link to it now.

Switch your profile: The default profile is a client profile – this may have advantages that I am unaware of but in combination with Rhino and other assemblies you may experience errors, if you do not change the target to “.Net framework X“.

Editing the assembly is something I usually do, but did actually skip for TicTacToe. Without this your test framework can only see the public portions of the assembly. If you add [assembly: InternalsVisibleTo("")] to it this changes and the test assembly can also see the internals ot the assembly under test. That in turn allows you to control what portions are visible in the production code, since you don’t have to make everything public if you want to run a test on it.

Create your main method. The windows forms project comes with an application start. You wnat to edit that so it looks like this:

namespace TicTacToeTest
{
    static class Program
    {
        [System.STAThread]
        static void Main()
        {
            string fullPath = System.Reflection.Assembly.GetAssembly(typeof(Program)).Location;
            NUnit.Gui.AppEntry.Main(new string[] { fullPath });
        }
    }
}

This calls the NUnit GUI runner with the appropriate location of your test assembly. This is written universal so you can actually use it for all your test projects. The reason why you want to do this is because you use the Express version of Visual Studio. This version does not allow you to attach the debugger to a running assembly. So what you have to do is to start the assembly using the debugger – that way you can actually debug your test should anything go wrong. The downside is that you will get notified if an exception is thrown – even if that was intentional.

I do not include a playable link to the executeable. I think if you read it this far you may want to look at the sourcefiles instead. So here is the project instead. Human vs. Human version 001

TicTacToe Refined

I talked with a friend about the design and he pointed out that it seems too big for such a small game.

I have to admit that it is not obvious why I would go for that design. To illustrate why I want to do certain things he suggested to start with one godlike class. In successive expansions I will elaborate the design and install all those small objects. That way it will be easy to explain in small steps why I want them to be there.

The godobject was done so fast I did not even set up the whole project. I started with the view and did miss the point where I should have started to switch to TDD. For the same reason I missed the point where I should have tried out FXCop.

The godobject is now coded into the MainWindow-ViewModel. From a design point of view I coded the business logic into the layer that is meant to help isolate the logic. It shows how easy it is to get sucked into the WPF framework since it is so powerful.

Everything was very straigth forward except for one problem I discovered. During the project I recognized that I am unable to use data binding on a multidimentional array. This actually created an ArgumentException. I posted the problem on stackoverflow I may come back to this problem after I finished TicTacToe. Jagged arrays work just as fine, so I don’t want to divert from my goal too much. Post your suggestions in the comments or answer on stackoverflow (easy points for the taking).

You can play the Human vs. Human version 000, it looks like this:

The view itself consists of 9 buttons and a status text. Each button has a viewbox with a TextBlock inside instead of its regular content. This allows the X and O characters to scale up to whatever size the button is. In addition I use the buttons name to identity it after the click. All buttons call the mapClick on click.

I dont show the XAML here because I have bad experience with XML like content on this page. Post in the comments if you have a good solution for posting XML snipptes on wordpress.

The codebehind file of the main window is very slim. This is intentional to get to out of that file as fast as possible. For testing purposes you want this file small because you can not reasonably instantiate it. In this case I chose to create a Viewmodel inside the constructor. The alternative is to edit the APP and change the way the Mainwindow is created. There is usually some temporal coupling to InitializeComponent(). Here for instance you have to set the mapClick action before the call or a NullPointer exception occurs.

    public partial class MainWindow : Window
    {
        MainWindowViewModel vm;
        private Action<object, RoutedEventArgs> mapClick;
        public MainWindow()
        {
            this.DataContext = vm = new MainWindowViewModel();
            mapClick = vm.mapClick;
            InitializeComponent();
        }
    }

The MainWindow-ViewModel contains all the rest of the game. First I show it here and afterwards I talk about the things that are wrong with it.

    class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public Char[][] MAP { get { return _map_jagged; } }
        public String Systemstate { get {
                if (' ' != _winner) return "Player " + _winner + " has won the game.";
                if (turn > 9 ) return "The game ended in a tie.";
                return "Player " + _icons[(turn)% 2] + " has to move.";
            } }

        private void notify(String property) 
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
                PropertyChanged(this, new PropertyChangedEventArgs("Systemstate"));
            }
        }

        private Char[][] _map_jagged = {
                                       new Char[]{ ' ', ' ', ' ' }, 
                                       new Char[]{ ' ', ' ', ' ' }, 
                                       new Char[]{ ' ', ' ', ' ' }
                                       };

        private uint turn = 1;
        private Char[] _icons = { 'O', 'X' };
        private Char _winner = ' ';

        public void mapClick(object sender, RoutedEventArgs e)
        {
            if (sender is Button)
            {
                String name = (sender as Button).Name;
                int col = name[3] - '0';
                int row = name[4] - '0';
                mapProcess(col, row);
            }
        }

        public void mapProcess(int col, int row){
            if (GAMETryMarkMap(col, row, _icons[turn % 2]))
            {
                notify("MAP");                
            }
        }

        private bool GAMETryMarkMap(int col, int row, Char mark)
        {
            bool changed;
            if (' ' == _map_jagged[col][row] && ' ' == _winner)
            {
                GAMEMark(col, row, mark);
                changed = true;
            }
            else
            {
                changed = false;
            }
            return changed;
        }

        private void GAMEMark(int col, int row, Char mark)
        {
            uint n;
            _map_jagged[col][row] = mark;
            ++turn;
            for (n = 0; n < 3; ++n)
            {
                if (_map_jagged[n][0] != ' ' && _map_jagged[n][0] == _map_jagged[n][1] && _map_jagged[n][0] == _map_jagged[n][2]) _winner = _map_jagged[n][0];
                if (_map_jagged[0][n] != ' ' && _map_jagged[0][n] == _map_jagged[1][n] && _map_jagged[0][n] == _map_jagged[2][n]) _winner = _map_jagged[n][0];
            }
            if (_map_jagged[0][0] != ' ' && _map_jagged[0][0] == _map_jagged[1][1] && _map_jagged[0][0] == _map_jagged[2][2]) _winner = _map_jagged[0][0];
            if (_map_jagged[0][2] != ' ' && _map_jagged[0][2] == _map_jagged[1][1] && _map_jagged[0][2] == _map_jagged[2][0]) _winner = _map_jagged[0][2];
        }
    }

The easy things to say about it is that this object has a multitude of responsibilities. You can even see that some methods start with the name of an object they want to be connected with.

Systemstate is a generated string for the UI. It looks like a seperate object or concept that actually wants to exist. As a matter of fact the game can be represented by using a finite-state machineAt the point where the viewModel wants to get the state the call should look more like one of the following options:

public String Systemstate { get { return game.getState.ToString(); } }
public String Systemstate { get { return game.state.ToString(); } }
public String Systemstate { get { return game.stateString; } }

The map is an implementation detail that should be burried somewhere in the game object. It looks like the MainWindow-View wants a jagged array, but the adaption is what the viewModel is for – not the game itself. The game should not concern itself with how to implement the map. When we are done with the Map it will likely not be a jagged array but something else.It is likely that using a LinQ query will be easiest to implement the adaption.

All the small things like turn or playertoken should not be in the MainWindow-ViewModel. Maybe some of them should be part of a state, player, map or game.

The playertokens do bother me. There are three tokens in play at the moment: ‘X‘, ‘O‘ and ‘ ‘. The blank token is used to identify that no token is on the field. In the current design I have to check so that blank token does not win the game. ( _map_jagged[.][.] != ‘ ‘ ). This can actually be made to disappear with better design.

The players themselves are hidden in the tokens and in the turn variable. This is a problem because I can not add new versions of players. So in order to get the AI players in the game I have to extract the players.

Exploring what’s wrong is fun but right now one has to look at the backlog and ask what to do next. I will start with getting everything under test, since this is extremely important for refactoring. After tests I want to have that FXCop watching over me, so I will get that installed. The third step is to move everything out of the viewmodel into a game object. And at that point I will take another look at the design.

TicTacToe Project

The weekend is near and I have to decide how I will go about that TicTacToe game.

1. The first question I need to answer is what programming language to use.

Ansi C89/90

I am forced to use this during my week in my daily work. So doing TicTacToe in it would be a nice additional training. I may upload some thoughts about clean programming in C90 in the near future. My private time is very limited so I’d like to spend it efficiently. For that reason alone C90 is not an option.

C++ 11

I used to like C++ and I am understanding it even better now that I am forced to live without its comfort. C++ is important for modding FPS-Shooter-Games so that puts it on the top of my list for “need to train” and I may add a project in the future.

Java

Java is a very easy language. Always state of the art. Everything is free including refactoring tools. Using Eclipse as an IDE is cool because of the huge amount of automated upgrades. Considering Android and the future of the mobile plattform, it seems to be a good idea to use Java for a Tic Tac Toe app project in the future.

C#

Last but not least – I personally develope fastest in C# and there is a tool I never used and that I would like to learn. So C# will be my choice for this project.

2. The second question is about tools.

I plan on programming TicTacToe and deleting it afterwards from my harddrive, there will be a copy on this server – so I wont use a repository. For testing I will create a seperate project that connects to NUnit and gets access to internals of TicTacToe. I also  want to see FXCop from Microsoft in action. FXCop is a styleguard and will help me to conform to the C# default coding style. On the framework side of things I can currently only think about WPF for the GUI, the alternative would be XNA and i think that may be quite some overkill for this project.

3. The third question is how to develop the game.

So this is the last question before I start tomorrow. I am thinking what features to include and what I actually want to do. I just opened MS Paint and started sketching my program. As with any first draft this will change. I can already see that my integrationtests can fully run through the viewmodel. I also like the idea of having my map contain a representaion of the winning lines, this will make the rulepackage for the ruledriven AI easier. The map will also contain the same playertoken over and over again. Since the map already contains winning lines that will contain tokens I am unsure if the field concept will benefit me in the end. I think the fields are an implementation detail that will be superfluis.

I have to think a little bit more about how I want the players to make their move. The idea is that the gamecontroller triggers the move but that may not be possible. It could be that the gamecontroller should actually be a gameservice that accepts or denies moves and sends tokens in events to inform everybody that a new player earned the right to move – if I can get it done with a controller I will go for it, otherwise the players will be observers and the gamecontroller will be an observeable.

Here is my fingerpainted picture for your delight. Feel free to comment, especially if you have designimprovements for me.

Tic Tac Toe AI

I was just looking at some old projects and found a TicTacToe game i made at some point in the past. The code style is pretty bad and i am thinking about remaking it. I think it will be a nice little project that lends itself to my occasional spare time programming.

The thing about my old implementation that I wanted to share is the AI. It is a very simple script that was fun to play against as I remember. Four rules are sequentially checked, whatever rule applies first determines the selected field, and the AI makes its move accordingly.

The rules are:

  1. Win in one move possible? → win
  2. Enemy win possible? → block
  3. Center still available? → take center
  4. Any free fields? → randomly pick a free field

As I remember it the AI was quite pleasant. Good enough to not be boring. Bad enough to be beatable.

The AI will not hesitate to win (1). The player has to lay out a trap that consists of more than one win opportunity (2). The AI will try to get the strongest map position (3). No two Games are the same (4).

My next implementation will have a couple of different options.

  • Easy: A perfect AI trying to loose
  • Normal: A random selecting AI
  • Hard: The above AI
  • Impossible: A perfect AI trying to win

I will start a mini series for TicTacToe on this blog, if you have suggestions for the implementation feel free to comment.