Tetris Is Hard To Test
New submitter JackDW writes: Tetris is one of the best-known computer games ever made. It's easy to play but hard to master, and it's based on a NP-hard problem. But that's not all that's difficult about it. Though it's simple enough to be implemented in one line of BBC BASIC, it's complex enough to be really hard to thoroughly test.
It may seem like you can test everything in Tetris just by playing it for a few minutes, but this is very unlikely! As I explain in this article, the game is filled with special cases that rarely occur in normal play, and these can only be easily found with the help of a coverage tool.
It may seem like you can test everything in Tetris just by playing it for a few minutes, but this is very unlikely! As I explain in this article, the game is filled with special cases that rarely occur in normal play, and these can only be easily found with the help of a coverage tool.
If anybody wrote code like that for me, they'd be made to sit on the naughty step and think very, very hard about what they'd done.
I'm sure there is a joke in there somewhere.
Don't waste your vote! Vote for whoever you want, unless you live in a swing state it won't matter anyways
It may seem like you can test everything in Tetris just by playing it for a few minutes, but this is very unlikely! As I explain in this article, the game is filled with special cases that rarely occur in normal play, and these can only be easily found with the help of a coverage tool.
Tetris doesn't need coverage tool to test you. Everything about you.
Code-coverage tool is crutch for weak capitalist engineer. Tetris is Soviet technology, forged by people's will.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
From a company promoting automated WCET analysis. Hah!
Any language that doesn't require carriage return + linefeed can do anything in one line.
And Basic comes with a ton of library fuctions that makes things easier to do. No need to initialize memory, dispaly, setup graphic or keyboard interrupts, etc.
In BBC BASIC, a colon is a statement terminator, much like a semicolon in languages with C-style syntax. The linked code is therefore not a one-liner by any meaningful definition of the term. One could replace all of the linefeeds in Linux kernel source with semicolons and other appropriate terminators. That wouldn't make the kernel a one-liner.
Perlers are so jealous right now; they need 2 lines.
Table-ized A.I.
In BBC BASIC, a colon is a statement terminator, much like a semicolon in languages with C-style syntax. The linked code is therefore not a one-liner by any meaningful definition of the term. One could replace all of the linefeeds in Linux kernel source with semicolons and other appropriate terminators. That wouldn't make the kernel a one-liner.
If it's a one-line program, why is it more than one line?
A line of code is not the same as a line on a screen. The program won't fit on one line on most screens, but it will fit on one line of BBC BASIC, which fortunately has a well defined, but short maximum length of 256 characters. The whole program is 257 bytes as there is an extra byte to mark the end of the program.
from: http://survex.com/~olly/rheoli...
Be seeing you...
Yeah. The linked "one line" of code is at really least 50 lines by any sane metric.
hands?
This.
The fact that probability is involved doesn't mean there's not an optimal strategy, of course, where optimal is defined as "highest expected score" (score X probability). So figuring out an optimal strategy is a hard problem - how hard is it?
If the probability of a certain series of shapes coming next were 100%, we'd have an NP-hard problem, agreed? Does another probability make it easier or harder? Harder, if anything. That's provable because the probability version can be solved by solving each of the potential series as if each were known. What's harder than NP-hard? It may well still be NP-hard. It can't be of any more solvable complexity class.
So at some point you reach a point of diminishing returns. It might not be worth making sure every line got tested when there are procedures that have a bug that happens in one in a billion calls. My philosophy is, "Perfection is the goal. Doing better than the last release is the shipping criterion".
sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
Why would you only test your code via normal use? Why wouldn't you just create a test suite that actually tests all the scenarios? In the case of tetris, you can simply force a sequence of pieces that will enable you to reach the scenarios described in the article. Or you can even start the game with a pre-made board.
Has slashdot really become a means for tech companies to inject free advertisement by a simple blog post made to look like real journalism?
The article makes it sound like coverage tools help! If you're not familiar with them, they tell you which bits of code have been run, not how many of the N cases of that code have been executed.
So the code might fail with a particular combination of inputs, but the coverage tool is more interested in which bits of the code have been execute.
It's one of these tools and metrics that non-technical managers use to substitute for an ability to read code.
46 lines (statements), actually. There's a linked page where he blows it out into a readable form and explains how it works in depth.
Please stand clear of the doors, por favor mantenganse alejado de las puertas
In BBC Basic, a single line is 255 characters. RTFA.
"First they came for the slanderers and i said nothing."
It's a piece of cake... http://bitbar.org/blocks/cake.html?fields=9
46 statements doesn't count the additional whitespace necessary for readability.
Sane indentation adds one for every loop or non-oneline branch.
# newline
IF (condition)
STATEMENT
ELSE
STATEMENT
# newline
As I explain in this article, the game is filled with special cases that rarely occur in normal play, and these can only be easily found with the help of a coverage tool.
This doesn't seem like news to me! I'm shocked and appalled!
It's a 15 liner.
Note that the {CBM-x} represents the graphic on that particular key (press the c= key and the letter to produce it)
1 a$="efijefijefijefijbfjnhijkbfjnhijkijfgaefjijfgaefjefjkiefbefjkiefbbfjidefj"
2 a$=a$+"abeieijkaeijijkgabfjiefgehijebfj@abe@dhe":o=207:dime(o):forx=0to111
3 print," {CBM-M}"," {CBM-G}":p=asc(mid$(a$,x+1)):e(x)=(pand3)+(pand12)*10:next:m=2024
4 print," {CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}{CBM-T}":gosub6:goto7
5 pokei+e(r),c:pokei+e(r+1),c:pokei+e(r+2),c:pokei+e(r+3),c:c=160:r$="d":return
6 i=1152:r=h:c=32:gosub5:j=int(rnd(0)*7)*16:r=j:gosub5:r=h:h=j:i=i+9:return
7 gosub6:w=i:t=i:g=r:k=240:l=1278
8 gosub15:c=32:gosub5:r=-r*b-g*notb:g=r
9 i=w:w=i+40:gosub5:gosub15:ifbthen12
10 getk$:g=randkor((r-4*(k$="s"))and15)
11 t=w:w=w+(k$=l$)-(k$=r$):l=l+40:goto8
12 c=o:gosub5:m=m-(l0:w=-t*b-w*notb:l$="a":return
READY.
PRINT ""+-0
13 fors=ltol+(m-160-l)*qstep-1:pokes+11,peek(s-29):next:y=y-q:m=m+q*40:z=z+q
14 l=l+40*not-q:next:print"{home}";z:goto7
15 b=0:forx=0to3:b=bor1andpeek(w+e(g+x)):next:b=b>0:w=-t*b-w*notb:l$="a":return
{home} is the home character blob (appears as reverse S character) within quotes
Use A,S,D keys to rotate and drop the blocks
Have fun!
READY.
PRINT ""+-0
How long before The Tetris Company sends a notice of claimed infringement to Slashdot's designated agent, claiming that this post and others like it infringes the copyright in Tetris ?
What's harder than NP-hard?
Intractable.
True. Smiling Bob is also harder.
A line can be no more than 256 characters. That doesn't mean that the following is one line:
foreach mammal in pets
print mammal ' "is a mammal"
if (is_cat(mammal) {
print " and also a cat"
}
}
Just because all cats are mammals doesn't mean that all mammals are cats.
Just because all one-liners are less than 257 characters doesn't mean that all programs less than 257 characters are one-liners.
"For stories about boys in leather, please press 1..."
Defining all of the possible scenarios is often a lot harder than it looks. There aren't too many UI coders out there that haven't said "yeah, we need to fix it, but what made the user decide to do that?" at one time or another.
This reminded me of a UI bug I discovered in Steam - if you have 2 monitors, one rotated 90 degrees, but not the primary, and try to maximize steam on that window, bad things happen.
Seeing as how I've seen only like 3 people doing that, most not in a home setting, I don't think it comes up much.
I don't read AC A human right
So, on the one hand, it's sort of a spammy/advertisey thing to begin with.
On the other hand, I'm also not entirely convinced that the code coverage tool really solves the problem, because a given line of code can have different effects under different circumstances.
If you read in an address from a text stream, and then write to the memory location denoted, that's just one line of code executing that dereferences the pointer, but good luck determining what it does on all future invocations based on watching it execute once. Similarly, consider a straightforward loop like "for (i = 1; i len; ++i) a[i] = 0;" where every line will be hit if len is at least 1, but the effect of executing the code is, to put it mildly, somewhat variable.
My blog: http://www.seebs.net/log/ --- My iPhone/iPad app: http://www.seebs.net/seebsfrac/
I'm kinda glad that code coverage is difficult to do! ( http://en.wikipedia.org/wiki/Konami_Code )
Cheat codes and "Easter Eggs" give the lowly programmer a chance to do something awesome/notorious, against the long odds of getting stuff approved by marketing, the legal/IP department.
Unit testing is meant to do full code coverage from within an app. However, it can sometimes be quite difficult to set up the complete software state to test some kinds of scenarios, but this can be made easier if the program is designed with testing in mind. I don't know what kinds of projects would benefit from "test-driven design", though. Maybe life-critical software (aerospace, medical, Facebook).
Looks more like a programming problem than pnp.
> This procedure, updateScore4, is called when a block of 4 lines are cleared at once.
What kinda mid evil crap is that?
Testing !!!!! Is !!!!! Software Development !!! HAHAHAHAHA.
As others said, nice advertisement. In practice, however, such tools tend to guide people along an "easy" path, where two very basic principles are ignored.
a) The primary goal of every testing is check fulfillment of requirements. Even if coverage is reached, the same might not be true for completeness with regards to requirements. The tool may report "100%", but there is still cases described in the requirements that do not work.
b) Simply executing instructions is not worth anything towards proving code coverage. In addition it has to be shown that they positively contribute to the result. It is easily possible that some code executes incorrectly but without negative impact in a given test-case. The tool will report 100%. With a different test-case, it may still execute incorrectly and having an overall effect. If that test-case is missing the result is OK with full coverage and the product is still broken.
The one reason, and only reason, to check coverage is detection of dead code that will do something wrong when executed in situations not considered during testing. Mindless deployment of such tools distract from this. They tend to make "100% coverage" the goal, even though this is far from sufficient.
While I totally agree with the one-line bullshit, I'd just like to point out, that in fact, you can't collapse the linux kernel into a one-line statement this way; Parts of the code is using macros and they will fail if you put them on the same line.
46 lines (statements), actually
No, statements are not the same as lines. Lines have real semantic significance in BBC Basic, in a few different ways: for one, GOSUB-type subroutines can only start at the start of a line (because that's where the line number is), and you also can't terminate an "if" without starting a new line. That (plus the 256-byte limit) makes writing one-liners in the language more of a challenge than in other languages where line breaks genuinely aren't significant.
Need to type accents and special characters in Windows? Use FrKeys
what do you expect from a oneliner? Tetris()? A Perl Oneliner does have semicolons as well.
So you run cc -E first then
I guess today is a passable day to die.
The nice part about putting the entire Linux kernel on a single line is that you always know the exact line number of the bug.
How is this informative?
In old micro BASIC, lines have a meaningful and clear definition. They are ordered strings of tokens prefixed by a number and containing one or more sentences, usually limited to about 256 bytes in size. You can only edit the program a line at a time, and you must edit the entire line. The numbers are also used as labels for loops and subroutines. The concept of 'a line' is not only meaningful, but fundamental for the structure of the program. The linked code is a one-liner and absolutely nobody who had programmed BBC BASIC would say otherwise.
Your confusion comes from thinking about programs as text files or streams to be parsed or compiled. That is not how old BASIC works. The program was usually stored and edited in binary form, most of the time already tokenised more or less aggressively depending on the implementation.
Even if you want 'a line' to mean a line on screen, old micros usually had several switchable screen modes with different numbers of characters per row, so that makes less sense than the correct definition.
External interactions (DBs, UI, etc) and highly performant code (embedded systems, kernels, etc) are where I wouldn't instinctively look to use TDD.
The benefits around testing are massive in themselves - you can set up automated unit tests that assure you not just the code coverage, but also the broad range of inputs that might cause different behaviours within that code.
The design benefits however are significant too, and worthwhile in their own right. I find that TDD leads to code that's easier to read, understand and thus maintain.
It is a one-liner. Stop being a pedantic tit.
It is one continuous line, and I assume, no word wrap. (if there is, THAT would nullify it from being a one-liner)
A one-liner is basically a rap of the programming world. A syntactical mess waiting to happen if you do not watch what you are doing. (hint: most rappers don't and won't watch what they are doing either)
What it ISN'T, though, is a one-commander. That you would be correct with.
Commas also do not constitute a one-commander, it classifies as both an operator and a command seperator / terminator.
Well, eh, I guess it could count. It is a really grey area symbol.
Ignoratio elenchi
Confucius say, "Find worm in apple - bad. Find half a worm - worse."
While I totally agree with the one-line bullshit, I'd just like to point out, that in fact, you can't collapse the linux kernel into a one-line statement this way; Parts of the code is using macros and they will fail if you put them on the same line.
#include "kernel.c"
That's a one liner!
I am anarch of all I survey.
I knew I was missing something lately.
My dad and I wrote a BBC BASIC interpreter for PC-DOS. I'll have to dig it out and see if I can get this working in it.
As I mentioned, the test of fitness is expected value - the average score of 100,000,000,000 games played with that starstrategy, not the result from one specific, randomly chosen game.
In Hold'em folding preflop with pocket aces may turn out for the best occasionally, but it's still a bad policy because it will lose more than it will win. The best strategy is the one that does well long term.
...but not without a price. If you can mathematically construct your program then you can prove that it is free from defects providing enough assumptions hold (the specification is correct, the tools used to build it are correct, the proof of correctness is correct, you had enough money/time/skill to do the process etc). For the time being, it's not possible to formally most programs that have already been written in mainstream languages so other techniques like testing will remain useful tools.
But only on my second attempt once I learned about MC/DC :(
but only on the 2nd attempt once I read about MC/DC :(
Worrying: "Coverage metrics are frequently used as stopping criteria for the testing activity"
https://hal.archives-ouvertes.fr/file/index/docid/848458/filename/8_-_ars2013_Paper11_Johansson.pdf
Hi. Im not a code professionist but when i look at these lines i get a big head pain. Honestly i don't understand a thing , and i studied php in school. If somebody could give me some detalied steps,for my beginner language,maybe i could do this too.
Tractari Auto Iasi
Let me see if I correctly understand your point. Are you saying:
The best algorithm for a deterministic sequence may be / is NP-hard.
Best best algorithm for the stochastic sequence may be different.
Therefore, the best algorithm for the stochastic sequence may be easier than NP-hard.
That seems to make sense. Until you realize the deterministic sequence IS one case of the stochastic - where the probabilityof a certain sequence happens to be 1.00. If you had a polynomial algorithm for probability X, you could run it for X=1 to solve the deterministic version. Thus, if the deterministic version is NP-hard, so must be the stochastic version in general.
Of course, one specific, special case probability matrix may be solvable more readily. As someone else pointed out, if you decide that your specific version of Tetris generates square pieces always, the algorithm is trivial. However, if we seek an algorithm for any version of Tetris, any probability of any given piece, that will include probability 1 of a given sequence. Thus, the generalized stochastic includes the deterministic as one case and therefore must be at least as complex as that case.
you didn't write it correctly. TDD.
Does David Hassellhoff have any insightful blog posts on this subject? It sounds like his insight on burning man line queues could be beneficial here.
Dear God, the memes are reproducing like rabbits, soon we'll be overrun.
1) TETRIS may be NP hard to play optimal, but its not NP hard to implement
2) The one liner does not implement the same TETRIS, the code coverage tool vendor is writing about. He tries to cover special places in game scoring (in points) while the BASIC program does do any scoring at all.
From a company promoting automated WCET analysis. Hah! http://www.urlbuff.net/
So in other words, you're pointing out that you could just not solve it, not come up with the optimum move each time based on expected value. Instead, you could settle for a "good enough" move and sometimes you'd get lucky. This is true.
you stated:
stochastic:
best: np-hard, not perfect, quality unknown
other: polynomial, good average
You called the first algorithm "best", acknowledging that the best (best long- term average) is NP-hard. The other can't be better than the best (by definition) , so the problem of finding the best moves remains NP-hard. Sure you could have a simpler algorithm that comes up with reasonable moves, but it'll always be beaten by the NP-hard in the long term.