HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Snake Game in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
gamesnakestackoverflow

Problem

Recently, I have been trying to learn SOLID principles. I learn the best through criticism.

I made this snake game in Unity with C#, where I put my current understanding of SOLID principles to test. The game itself works wonderful, but I am trying to write better code.

Main questions:

  • What principles am I breaking? And how can I fix them?



  • Should I use interfaces instead of polymorphism?



Other:

  • Am I doing any bad practises?



  • Is my design bad?



I don't know Unity and can't read your code

Dont worry, I barely use Unity in this game. Everything should be understandable.

Explaining my solution:

My solution is to have all objects placed in positions in a "grid". Multiple objects can be at any positions. Logic is handled in Before(), Next() and After() in all of the objects. These are called every 0.1 seconds (or per step).

Every object is independent. There are direction objects that are placed whenever the user presses a key. When a snakepart is at the same position of this direction object, then the snakepart gets that direction. The direction obj is deleted once it no longer is at a position with a snakepart.

IVector2 is simply a class with int x and int y. It has nothing to do with interfaces (bad naming, my bad).

Own Comment

The number of files is ridiculous for such a small game. And it took some time too. However, bugs were INCREDIBLE easy to find and deal with. Loved it.

If you like anything, feel free to use it. I may upload the project, if it is requested. I can also upload a video of the final project, if so desired.

Filenames overview:

  • Game.cs: Monobehavior - Start is called once on start, Update is called every frame



  • CreateGame.cs



  • DeleteGame.cs



  • GameOver.cs



  • InputHandler.cs



  • Score.cs



  • Snake.cs



  • ObjFactory.cs



  • Direction.cs



  • GameObjectInstantiator.cs



Objs

  • Obj.cs: base class



  • VisualObj.cs: Obj



  • AppleObj.cs: VisualObj



  • SnakePartObj.cs: VisualObj - Each individual part of the snake



  • BarrierObj.

Solution

Just a few remarks. Reviewing bottom-up.

public class MultipleValuesDictionary


Don't name classes dictionary if they aren't one (implementing the IDictionary interface). It's confusing.

You can derive a type from the dictionary instead of implementing only parts of it and inventing new vocabulary for it.

Don't come up with new generic parameters names. The conventions is to start the names with the uppercase letter T.

You could simply define it as:

public class MultipleValuesDictionary : Dictionary> { }


public List GetValuesOfTypeAtKey(key k) where T : value
{
    HashSet values = GetValues(k);
    return values.Where(o => (o.GetType() == typeof(T))).ToList();
}


No dictionary should have such method. It's a special case and you could easily get what you need with the OfType extension:

var results = multipleValueDictionary[key].OfType().ToList();


public class DataBase 


This is an interesting class with an even more interesing naming convention:

public void AddEntry(key key, obj obj)


Don't! Use TKey and TValue.

The private objectsHash doesn't seem like it was necessary. The only place you use it for is

public HashSet GetAllObjects()
{
    return objectsHash;
}


where you could simply use SelectMany

dictionary.Values.SelectMany(x => x)


public class DirectionObj : Obj


Everything seems to be either an Obj or have the suffix -Obj. Calling everything obj in an OO language is like you ware calling every-thing a thing. No one would understand you.

public Direction dir { get; set; }


Property names -> PascalCase. No abbreviations.

dir.direction = Direction.names.Up;


The code lacks consistency but the Obj suffix :-)

Code Snippets

public class MultipleValuesDictionary<key, value>
public class MultipleValuesDictionary<TKey, TValue> : Dictionary<TKey, HashSet<TValue>> { }
public List<value> GetValuesOfTypeAtKey<T>(key k) where T : value
{
    HashSet<value> values = GetValues(k);
    return values.Where(o => (o.GetType() == typeof(T))).ToList();
}
var results = multipleValueDictionary[key].OfType<MyType>().ToList();
public class DataBase <key,obj>

Context

StackExchange Code Review Q#151854, answer score: 17

Revisions (0)

No revisions yet.