domingo, dezembro 03, 2017

Thinking in Code: "Antao's Tetris Ported from Python"


If you want to have a go at my version of the game, you can install it from here at the Google Play Store (Python version running on the Chrome Browser here).

The above app layout was modelled after my own gameboy:


Compare both pictures above. Was I successful? You tell me!

Any idiot can code, and many do. The skill is in understanding the maths and algorithms (speaking as an idiot who codes).

Lazy (or to be fair perhaps just poorly informed) people have taken to use the word "coding" as a synonym for software development. Actually, coding is tricky in and of itself (read the C++11 reference manual and tell me it ain't so) but it is still only the "bricklaying" part of construction, so to speak. Programming is creative and exploratory and stimulating to the imagination. It's a different way of thinking that serves people well in all sorts of life situations outside of software. So as a way to develop skills in logical thinking, problem solving and invention it's very useful. Not every child will go on to write software as an adult but having a basic understanding and insight into systems has to be a fundamental part of every child's education I say. If you don't understand the systems controlling your life how can you ever use them to your best advantage?

Actually the basics of code are not directly computer related at all. A simple binary device is an on-off light switch which says something like when I am 'on' my user is at home and when I am 'off' my user is away. A second light switch allows this develop into when both lights are on my user is awake and when only one light is on my user is asleep and so on. The code is what you make the light sequences mean. The same use is made of morse code, an abacus, flag signals , hand gestures, anything that can be logically explained to mean something for each different state. I think most children develop logic rather more quickly than we believe possible, and the only problem with computers is demystifying their apparent complexity when they are only ever very fast at very simple arithmetic and being given very precise instructions about what to do with all that speed adding numbers together.

I have to say that contemporary programming is much poorer than it was ten years ago, and I believe that is because we have provided far too many lazy ways to do complex things without making students graft hard at the basics and that is where I do believe improvements are to be found. However , ask a 20 something year old to sit there all day and write "select from where" ad infinitum and it doesn't take long to realise why younger people are not motivated by "heavy lifting" programming...

Programming is easy. Like any language, it is easy once you know how to talk, and think it. We have to stop thinking of programming as mathematics, science or engineering. It needs to be taught as a language skill. The moment we treat it as a language skill, the traditional barriers begin to fall. It becomes acceptable for parents of both sexes, at any age, and any religion. I don't think there are many people who would object to their kids having the opportunity to learn multiple languages, as early as possible, if they could. I don't think I have ever heard anyone object to a child being able to speak multiple languages. Once academics can get over their misconceptions on what they need programming to be, we could all move on, and start teaching our kids how to make them look stupid.

Once you can program in one language it is easy enough with the help of Google to pick up other languages. I've spent quite a lot of time programming in languages that I didn't know. In my experience what people find harder to pick up is the logic and the ability to break down the task required into the small logical steps required to make a computer perform the task. I started out very young; I learned to program because I wanted to play games and back then that meant typing in program listings from computer magazines. They never worked properly so I worked out how to fix them. Do a few of those, and you soon enough prick up how to program. After that new languages are easy. The only time I struggled a little bit was in making the leap from procedural coding to object-orientated as that's a bit of a paradigm shift.

I used to be a software developer, and have developed lots of software for the last 25 years. Believe me when I tell you that 99% of the job, has nothing to do with either mathematics, or science. The only reason you, and most other people, who probably don't program, think it does, is because everyone you ever see, working in this branch, drives that, image. Syntax is language, but expression is also language. Being able to understand, and then describe a process, is absolutely, a pure language skill. Most of the work ever done, is little more than connecting dots, and building logical expressions with existing tools and libraries. The language behind every programming language, is pretty much universal. once you have learned how to express yourself, and approach problems, you can easily skip to any language, and syntax, with a short learning curve. Ask a database developer, or a network developer how much math and science they need, to do their job. Not a lot, that is for sure. some do, but in general, very little real math is required, and it sure ain't rocket science these days. of course further skills are required in some areas, depending on what you want to do, but I would argue with anyone that this job is generally NOT science anymore. I would also argue that that math is absolutely NOT a prerequisite to be able to program today. If you are a good communicator, and you have normal math skills, you can be a great programmer. If IMO, we exclude the wrong people from programming. We need less geeks with personality disorders in this branch, and more talented communicators. To get that, we need to rethink who we think are going to be good at the job, and include a completely different skill set, as prerequisite to what makes a programmer today.

I still sometimes dream of creating some games and getting a bit of cash from it. I still tinker with Android (a few more examples of coding in Android here), and have a few half-finished games that I did in XNA for the Xbox Live Indie store. I think part of the problem for games now, or at least console games, is the publisher and retailer taking so much of the pie. Digital distribution is great in principle, but on console at least, unless you're using Xbox Live Gold or PSN+ or whatever there seems to be absolutely no discount - in fact a lot of games are more expensive than their retail counterpart (which is expensive and fickle enough). If a developer could get a lot more of the money without going through a publisher or retailer, I'd be all for it. At the moment, the vast, vast majority of games I buy are old ones (2 years old or more) that you just can't buy new, so it's all second hand. This extra money, if going to the developers themselves, would give them a lot more freedom and make conditions at them a lot more tolerable.

As for "thinking in code", I used to be the same. I could have code swimming around in my head for hours, and to an extent still do (only now, with me doing a lot of QLIK work too, a lot of mine is maps, statistics and graphs). The experience hasn't put me off playing games, but given me more respect for the people that make them - and then, sometimes, less respect when they get things wrong, especially design-wise (Dead Rising's save system, I'm looking at you).


NB: The core of the engine is the following class.

class TetrisGame implements PosPaintable {
    Grid playfield;
    TetrisPiece piece;
    int curScore;
    int px,py; 
    intNonZero testNonZero;
    intOr      putDown;

    public TetrisGame(int xs,int ys,boolean randomCrap)
{
playfield=new Grid(xs,ys,1);
clear();
piece = new TetrisPiece();
py=0;
px=(xs-piece.sizex())/2;
testNonZero = new intNonZero();
putDown = new intOr();
curScore=0;
}
    
    void clear()
{
playfield.fill(0,0,playfield.sizex(),playfield.sizey(),0);
}

    public void paint(Graphics g, int x,int y)
{
g.drawRect(x,y,2+playfield.sizex()*10,2+playfield.sizey()*10);
for(int j=0;j
    for(int i=0;i
if((playfield.grid[i][j]!=0) ||
   ((i>=px) && (i
    (j>=py) && (j
    (piece.grid[i-px][j-py]!=0)))
    g.fillRect(3+x+i*10,3+y+j*10,8,8);
        }


    public boolean step()
{
if(playfield.compare(piece,px,py+1,testNonZero))
    {
    // Put down the piece
    playfield.put_on(piece,px,py,putDown);
    // Clear out full lines
    for(int j=playfield.sizey()-1;j>=0;j--)
while(testFullLine(j)==true)
    {
    deleteLine(j);
    // Simple scoring function
    curScore+=10;
    }

            // Put on a new piece
    piece = new TetrisPiece();
    py=0;
    px=(playfield.sizex()-piece.sizex())/2;
    if(playfield.compare(piece,px,py,testNonZero))
return true;
            }
        py++;
return false;
        }

    private boolean testFullLine(int y)
{
for(int i=0;i
    if(playfield.grid[i][y]==0)
return false;
        return true;
}

    private void deleteLine(int y)
{
for(int j=y;j>0;j--)
            for(int i=0;i
playfield.grid[i][j]=playfield.grid[i][j-1];
        for(int i=0;i
    playfield.grid[i][0]=0;
        }

// Data-returning methods

    public int score()
{
return curScore;
}

// Game-play interface methods

    public void move_left(int i)
{
if(playfield.compare(piece,px-i,py,testNonZero))
    return; // Should we throw an exception here?
        px-=i;
}
    public void move_left()
{
        move_left(1);
}

    public void move_right(int i)
{
if(playfield.compare(piece,px+i,py,testNonZero))
    return; // Should we throw an exception here?
        px+=i;
}
    public void move_right()
{
        move_right(1);
}

    public void rotate_cw()
{
TetrisPiece test=new TetrisPiece(piece);
        test.rotate_cw();
if(!playfield.compare(test,px,py,testNonZero))
    piece=test;
        }

    public void rotate_ccw()
{
TetrisPiece test=new TetrisPiece(piece);
        test.rotate_ccw();
if(!playfield.compare(test,px,py,testNonZero))
    piece=test;
        }

    public void drop()
{
while(!playfield.compare(piece,px,py+1,testNonZero))
    py++;
        }







7 comentários:

Luís Filipe Franco disse...

Great port! ;) you did a great job in getting that old style gameboy feeling

Manuel Antão disse...

Took me almost a year (started in January 2017...). A kid out of college would have made this in a month... Alas, I'm no longer a kid out of college. My business and private life do not leave much room for more.

Glad you liked it. You were the only one who made a comment... (*sigh*). Thanks buddy. Much appreciated.

Book Stooge disse...

I didn't comment because I wasn't sure what the point of it was and I didn't want to hurt your feelings :-)

There are already so many tetris clones out there, for free, you know?

Manuel Antão disse...

Boostooge, I do things for fun. I don't care what's out there. First and foremost, I want to check whether I still got what it takes...

Thanks for commenting.

NB: Don't be afraid to hurt my feelings; give me lots of stick when it's warranted.

Manuel Antão disse...

I think cheese can be a tad boring in a sandwich, although I am a big fan of eating cheese on its own. I am partial to a decent Cheddar grated with British Cox apples in top notch white crusty bread and cucumber. Failing that slabs of cheddar with sliced tomatoes. Grated cheddar and onion and NO mayonnaise (I hate it and if I get even the merest drop on my taste buds, a psychedelic yodel will follow) has a place too, easy to prepare a mountain of sandwiches quickly. Be careful to assemble it so that the cucumber doesn't come into close contact with the Marmite though or you get liquid brown run off which is not very pleasant, use the cheese as a buffer between them.

Question for you: do you prefer your cheddar to be naked or do you prefer to be naked whilst eating a sandwich :-) ?

NB: I'm going out on a limb here, but marmite and cheese is bloody lovely

Book Stooge disse...

See, I think cheese can make or break a sandwich. I am a big fan of cheese on its own though.

Since I tend to eat sandwiches at work, eating them naked really isn't a choice :-D So I'd say I'd prefer my cheddar naked. I'm good with buying a 5lb [2.25k] block of white cheddar and just paring off a bit every day to eat on it's own.

Never had marmite,but from how I've heard it described, I doubt I would try it now. If I'd grown up with it, I might be a huge fan, but now? Not going to try it...

Manuel Antão disse...

Ah yes. Marmite with cheese. I dare say it's an acquired taste...