Programming without the race: learning C#, a healthy rhythm and Snake
A practical workshop for developers: soft skills, sustainable work, learning C# through feedback, a console Snake game and a work-style survey with results by email.
The full article is available below. Enable JavaScript to use quizzes and simulations.
A workshop in C# and working well
Programming is not a race against time. It is the art of making good decisions with a limited attention budget.
You can spend ten hours coding and still not know whether you solved the right problem. Or you can spend forty-five minutes building a small experiment, checking an assumption, recording a conclusion and making it easier to return tomorrow without reconstructing the entire context.
This material combines soft skills, hands-on C# and deliberate rest. Along the way, you will build a console Snake game inspired by the simplicity of old mobile phones, make three design decisions and discover your dominant working style.
Change the metric first
Long hours are not the same as valuable work
In programming, it is easy to confuse effort with progress. The editor is open, the keyboard is busy and browser tabs keep multiplying. But a product does not benefit from the number of actions you take. It needs reduced risk, a tested hypothesis, a clear contract or a feature that can be safely accepted.
Before starting a work block, write down one sentence: how will I know this block was worthwhile? A good answer is observable: a test reproduces the bug, an endpoint returns the right contract, the player moves a single character, or the team knows the decision and who owns it.
This says nothing about whether the problem was understood or the change is safe.
This shows that we know more after the work and can take the next step.
This lets you return tomorrow without loading the whole problem back into your head.
After 70 minutes of debugging, you are no longer seeing new clues. What gives you the best chance of making progress?
I stay at the screen until the problem goes away
I write down my hypotheses, take a proper break and return with one new test
Choose a response and explore its cost.
45 minutes of work + 15 minutes to restore attention
One hour can be a complete learning loop
This is not about following a clock rigidly. It is about boundaries that make you seek feedback. If a task does not fit the loop, reduce the outcome you are aiming for. Do not add more hours to poorly defined work.
Mini-game: arrange the loop
Which sequence teaches you faster than reading alone?
Run and observeCollect a specific result or error.
Name one outcomeOne behaviour, not the whole system.
Step away from the screenConsolidate what you learned and restore your attention.
Build the smallest stepThe code should answer one question.
Explain it in your own wordsRecord the decision and the next question.
Start by defining the outcome.
Arrange again
Soft skills that hold up in production
The most expensive mistakes often begin with a sentence nobody clarified
Soft skills are not an optional extra alongside technical work. They synchronise different mental models. A developer, product owner and user can use the same words while imagining three different outcomes. Code simply makes one of those interpretations permanent.
Instead of asking “what should I do?”, ask: who makes this decision, what input state is valid, how will we recognise success, and what should happen when something fails? Those four answers often remove more work than another library.
Describes the context, observation, attempt and exact unknown.
Lets others challenge the direction before expensive code is written.
Separates the person from the decision and a blocker from a suggested improvement.
Communicates risk while the team can still change its plan.
“I do not know” is a professional answer when it comes with a plan to find out. Pretending to be certain creates debt that production usually ends up paying.
A reviewer writes only “this is wrong”. Which response is most likely to improve quality?
I ask which contract is broken, what the risk is and what behaviour is expected
I defend the implementation because it works on my machine
Choose the approach that turns an opinion into a decision.
Learning through a working model
C# gets easier when every concept has a job
Beginners often try to memorise a language chapter by chapter: types, loops, classes, collections. The problem is that knowledge without behaviour quickly fades. A game gives each element a responsibility. A position describes a point, an enum describes direction, a collection holds the snake's body, a loop represents time, and the update method makes one state change.
You do not need to know all of C# to begin. You need a small map and quick feedback from the compiler. Write one step, run it, name the result and only then add another rule.
An X/Y pair describes a location without hidden state.
An enum limits direction to four valid values.
The first element is the head, the last is the tail, and the cost of moving is clear.
One place manages the rules, score, food and pace.
internal readonly record struct Position(int X, int Y)
{
public static Position operator +(Position left, Position right) =>
new(left.X + right.X, left.Y + right.Y);
}
internal enum Direction
{
Up,
Right,
Down,
Left
}
Project: Snake in the console
First one character. Then a rule. Finally, a game.
A classic game makes a good laboratory because you can see the result immediately. Do not start with scores, food and colours. Draw the board first. Then move the head. Next, add the body and collisions, and only then adjust the pace.
Download the full Program.cs Download SnakeLab.csprojA loop over X and Y teaches coordinates.
Convert a direction into a position change.
A new head enters; the old tail leaves.
Keeping the tail makes the snake longer.
A wall or the snake's own body ends the round.
private void Update()
{
_direction = _nextDirection;
var head = _snake.First!.Value;
var next = head + Delta(_direction);
var grows = next == _food;
var tail = _snake.Last!.Value;
var hitsWall =
next.X <= 0 || next.X >= _width - 1 ||
next.Y <= 0 || next.Y >= _height - 1;
// Moving into the current tail position is safe
// if the tail is removed during the same step.
var hitsBody = _occupied.Contains(next) && (grows || next != tail);
if (hitsWall || hitsBody)
{
_running = false;
return;
}
AddHead(next);
if (grows)
{
_score += 10;
SpawnFood();
return;
}
var removedTail = _snake.Last!.Value;
_snake.RemoveLast();
_occupied.Remove(removedTail);
}
The snake's head moves into the cell currently occupied by its tail. Is that always a collision?
Yes, every occupied cell ends the game without exception
No, during a normal move the tail leaves in the same update
Think about the state before and after one game step.
A simulation of useful feedback
See how a small step turns an idea into knowledge
Run the flow: goal, code, compilation, observation, note and break.
Run the loop
Measurement without micromanagement
A tool should reveal your rhythm, not punish you for thinking
A timer can help you notice breaks and context switching. Commit history can show the size of your steps. A task board can limit work in progress. None of these tools can judge the quality of a decision on its own.
Measure only what leads to a conversation or an experiment. If a chart changes no behaviour, it is decoration. If it creates pressure to look constantly active, it harms the work it was meant to support.
| Need | Simple tool | What to measure | What not to conclude |
|---|---|---|---|
| Protecting focus | System timer | Number of completed blocks | More blocks do not mean better code |
| Learning C# | Experiment journal | Question, result, explanation in your own words | Pages read do not measure understanding |
| Team flow | A board with a WIP limit | Task age and blockers | A blocked developer is not a “slow developer” |
| Safe change | A test and a small commit | Time to feedback and ability to roll back | Commit count is not productivity |
A starting plan
Seven days to learn more without giving up your evenings
- Day 1Run an empty console application and draw a frame.
- Day 2Add Position, Direction and movement for one character.
- Day 3Introduce the body collection and safe tail handling.
- Day 4Add a point, growth and random selection of an empty position.
- Day 5Separate Update and Render; name their responsibilities.
- Day 6Write three rule tests without running the console.
- Day 7Explain the project in your own words and remove unnecessary code.
Now explore your profile
Do not look for the perfect method. Find a system you can repeat.
The survey below does not judge whether you are a good developer. It identifies how you most often approach uncertainty: through a map, an experiment, a relationship or a rhythm. After confirming your email, you will receive a strength, a warning sign and one seven-day experiment. Your address is used to verify and send your result.