800 lines

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

heartbone wrote:For the PureBasic development team, I have two questions about the demo-version.
1) Are comments part of the 800 lines?
2) Is the restriction 800 lines, or 800 statements?
Perhaps I am expected to install the thing, and construct some test source to get my answers? :?: :(
Keep it BASIC.
Lubos
Enthusiast
Enthusiast
Posts: 167
Joined: Tue Feb 03, 2004 12:32 am
Contact:

Re: 800 lines

Post by Lubos »

Code: Select all

OpenWindow(0,10,10,500,500,"800 line")

TextGadget(1,10,20,100,50, "Hallo world!")
;Line1
;Line2
;Line3
;Line4
;Line5
;Line6
;Line7
;Line8
;Line9
;Line10
;Line11
;Line12
;Line13
;Line14
;Line15
;Line16
;Line17
;Line18
;Line19
;Line20
;Line21
;Line22
;Line23
;Line24
;Line25
;Line26
;Line27
;Line28
;Line29
;Line30
;Line31
;Line32
;Line33
;Line34
;Line35
;Line36
;Line37
;Line38
;Line39
;Line40
;Line41
;Line42
;Line43
;Line44
;Line45
;Line46
;Line47
;Line48
;Line49
;Line50
;Line51
;Line52
;Line53
;Line54
;Line55
;Line56
;Line57
;Line58
;Line59
;Line60
;Line61
;Line62
;Line63
;Line64
;Line65
;Line66
;Line67
;Line68
;Line69
;Line70
;Line71
;Line72
;Line73
;Line74
;Line75
;Line76
;Line77
;Line78
;Line79
;Line80
;Line81
;Line82
;Line83
;Line84
;Line85
;Line86
;Line87
;Line88
;Line89
;Line90
;Line91
;Line92
;Line93
;Line94
;Line95
;Line96
;Line97
;Line98
;Line99
;Line100
;Line101
;Line102
;Line103
;Line104
;Line105
;Line106
;Line107
;Line108
;Line109
;Line110
;Line111
;Line112
;Line113
;Line114
;Line115
;Line116
;Line117
;Line118
;Line119
;Line120
;Line121
;Line122
;Line123
;Line124
;Line125
;Line126
;Line127
;Line128
;Line129
;Line130
;Line131
;Line132
;Line133
;Line134
;Line135
;Line136
;Line137
;Line138
;Line139
;Line140
;Line141
;Line142
;Line143
;Line144
;Line145
;Line146
;Line147
;Line148
;Line149
;Line150
;Line151
;Line152
;Line153
;Line154
;Line155
;Line156
;Line157
;Line158
;Line159
;Line160
;Line161
;Line162
;Line163
;Line164
;Line165
;Line166
;Line167
;Line168
;Line169
;Line170
;Line171
;Line172
;Line173
;Line174
;Line175
;Line176
;Line177
;Line178
;Line179
;Line180
;Line181
;Line182
;Line183
;Line184
;Line185
;Line186
;Line187
;Line188
;Line189
;Line190
;Line191
;Line192
;Line193
;Line194
;Line195
;Line196
;Line197
;Line198
;Line199
;Line200
;Line201
;Line202
;Line203
;Line204
;Line205
;Line206
;Line207
;Line208
;Line209
;Line210
;Line211
;Line212
;Line213
;Line214
;Line215
;Line216
;Line217
;Line218
;Line219
;Line220
;Line221
;Line222
;Line223
;Line224
;Line225
;Line226
;Line227
;Line228
;Line229
;Line230
;Line231
;Line232
;Line233
;Line234
;Line235
;Line236
;Line237
;Line238
;Line239
;Line240
;Line241
;Line242
;Line243
;Line244
;Line245
;Line246
;Line247
;Line248
;Line249
;Line250
;Line251
;Line252
;Line253
;Line254
;Line255
;Line256
;Line257
;Line258
;Line259
;Line260
;Line261
;Line262
;Line263
;Line264
;Line265
;Line266
;Line267
;Line268
;Line269
;Line270
;Line271
;Line272
;Line273
;Line274
;Line275
;Line276
;Line277
;Line278
;Line279
;Line280
;Line281
;Line282
;Line283
;Line284
;Line285
;Line286
;Line287
;Line288
;Line289
;Line290
;Line291
;Line292
;Line293
;Line294
;Line295
;Line296
;Line297
;Line298
;Line299
;Line300
;Line301
;Line302
;Line303
;Line304
;Line305
;Line306
;Line307
;Line308
;Line309
;Line310
;Line311
;Line312
;Line313
;Line314
;Line315
;Line316
;Line317
;Line318
;Line319
;Line320
;Line321
;Line322
;Line323
;Line324
;Line325
;Line326
;Line327
;Line328
;Line329
;Line330
;Line331
;Line332
;Line333
;Line334
;Line335
;Line336
;Line337
;Line338
;Line339
;Line340
;Line341
;Line342
;Line343
;Line344
;Line345
;Line346
;Line347
;Line348
;Line349
;Line350
;Line351
;Line352
;Line353
;Line354
;Line355
;Line356
;Line357
;Line358
;Line359
;Line360
;Line361
;Line362
;Line363
;Line364
;Line365
;Line366
;Line367
;Line368
;Line369
;Line370
;Line371
;Line372
;Line373
;Line374
;Line375
;Line376
;Line377
;Line378
;Line379
;Line380
;Line381
;Line382
;Line383
;Line384
;Line385
;Line386
;Line387
;Line388
;Line389
;Line390
;Line391
;Line392
;Line393
;Line394
;Line395
;Line396
;Line397
;Line398
;Line399
;Line400
;Line401
;Line402
;Line403
;Line404
;Line405
;Line406
;Line407
;Line408
;Line409
;Line410
;Line411
;Line412
;Line413
;Line414
;Line415
;Line416
;Line417
;Line418
;Line419
;Line420
;Line421
;Line422
;Line423
;Line424
;Line425
;Line426
;Line427
;Line428
;Line429
;Line430
;Line431
;Line432
;Line433
;Line434
;Line435
;Line436
;Line437
;Line438
;Line439
;Line440
;Line441
;Line442
;Line443
;Line444
;Line445
;Line446
;Line447
;Line448
;Line449
;Line450
;Line451
;Line452
;Line453
;Line454
;Line455
;Line456
;Line457
;Line458
;Line459
;Line460
;Line461
;Line462
;Line463
;Line464
;Line465
;Line466
;Line467
;Line468
;Line469
;Line470
;Line471
;Line472
;Line473
;Line474
;Line475
;Line476
;Line477
;Line478
;Line479
;Line480
;Line481
;Line482
;Line483
;Line484
;Line485
;Line486
;Line487
;Line488
;Line489
;Line490
;Line491
;Line492
;Line493
;Line494
;Line495
;Line496
;Line497
;Line498
;Line499
;Line500
;Line501
;Line502
;Line503
;Line504
;Line505
;Line506
;Line507
;Line508
;Line509
;Line510
;Line511
;Line512
;Line513
;Line514
;Line515
;Line516
;Line517
;Line518
;Line519
;Line520
;Line521
;Line522
;Line523
;Line524
;Line525
;Line526
;Line527
;Line528
;Line529
;Line530
;Line531
;Line532
;Line533
;Line534
;Line535
;Line536
;Line537
;Line538
;Line539
;Line540
;Line541
;Line542
;Line543
;Line544
;Line545
;Line546
;Line547
;Line548
;Line549
;Line550
;Line551
;Line552
;Line553
;Line554
;Line555
;Line556
;Line557
;Line558
;Line559
;Line560
;Line561
;Line562
;Line563
;Line564
;Line565
;Line566
;Line567
;Line568
;Line569
;Line570
;Line571
;Line572
;Line573
;Line574
;Line575
;Line576
;Line577
;Line578
;Line579
;Line580
;Line581
;Line582
;Line583
;Line584
;Line585
;Line586
;Line587
;Line588
;Line589
;Line590
;Line591
;Line592
;Line593
;Line594
;Line595
;Line596
;Line597
;Line598
;Line599
;Line600
;Line601
;Line602
;Line603
;Line604
;Line605
;Line606
;Line607
;Line608
;Line609
;Line610
;Line611
;Line612
;Line613
;Line614
;Line615
;Line616
;Line617
;Line618
;Line619
;Line620
;Line621
;Line622
;Line623
;Line624
;Line625
;Line626
;Line627
;Line628
;Line629
;Line630
;Line631
;Line632
;Line633
;Line634
;Line635
;Line636
;Line637
;Line638
;Line639
;Line640
;Line641
;Line642
;Line643
;Line644
;Line645
;Line646
;Line647
;Line648
;Line649
;Line650
;Line651
;Line652
;Line653
;Line654
;Line655
;Line656
;Line657
;Line658
;Line659
;Line660
;Line661
;Line662
;Line663
;Line664
;Line665
;Line666
;Line667
;Line668
;Line669
;Line670
;Line671
;Line672
;Line673
;Line674
;Line675
;Line676
;Line677
;Line678
;Line679
;Line680
;Line681
;Line682
;Line683
;Line684
;Line685
;Line686
;Line687
;Line688
;Line689
;Line690
;Line691
;Line692
;Line693
;Line694
;Line695
;Line696
;Line697
;Line698
;Line699
;Line700
;Line701
;Line702
;Line703
;Line704
;Line705
;Line706
;Line707
;Line708
;Line709
;Line710
;Line711
;Line712
;Line713
;Line714
;Line715
;Line716
;Line717
;Line718
;Line719
;Line720
;Line721
;Line722
;Line723
;Line724
;Line725
;Line726
;Line727
;Line728
;Line729
;Line730
;Line731
;Line732
;Line733
;Line734
;Line735
;Line736
;Line737
;Line738
;Line739
;Line740
;Line741
;Line742
;Line743
;Line744
;Line745
;Line746
;Line747
;Line748
;Line749
;Line750
;Line751
;Line752
;Line753
;Line754
;Line755
;Line756
;Line757
;Line758
;Line759
;Line760
;Line761
;Line762
;Line763
;Line764
;Line765
;Line766
;Line767
;Line768
;Line769
;Line770
;Line771
;Line772
;Line773
;Line774
;Line775
;Line776
;Line777
;Line778
;Line779
;Line780
;Line781
;Line782
;Line783
;Line784
;Line785
;Line786
;Line787
;Line788
;Line789
;Line790
;Line791
;Line792
;Line793
;Line794
;Line795
;Line796
;Line797
;Line798
;Line799
;Line800
TextGadget(2,10,200,100,50, "This is line 804 !")
Repeat
    Event = WaitWindowEvent()

    If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
      Quit = 1
    EndIf

  Until Quit = 1
  


End   ; All the opened windows are closed automatically by PureBasic

Try it! :lol:
Windows 7 Professional / Service Pack 1 - 32bit, PureBasic 5.46 LTS (x86)
My mother tongue is Czech. I have a Czech version of Windows.
Who is not afraid of GOTO, the one need not afraid any things!
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

Not knowing the effects on an existing install, I have not downloaded the demo.
Do you have any knowledge of answers to my questions about the ambiguous documentation?
Should I translate my questions into French?

Pour l'équipe de développement de PureBasic, j'ai deux questions au sujet de la version de démo.
1) Etes commentaires partie des 800 lignes?
2) La restriction 800 lignes, soit 800 déclarations?

(Google translated.)

I really shouldn't have to resort to empirical testing for these two answers, they should come from the authoritative source.
Keep it BASIC.
Lubos
Enthusiast
Enthusiast
Posts: 167
Joined: Tue Feb 03, 2004 12:32 am
Contact:

Re: 800 lines

Post by Lubos »

I'm not used to discuss what I do not know. Although I admit that in my country it is common. :wink:
I also did not know the demo version. But I downloaded it for testing.
Comments are calculated. Blank lines are also counted. The total number of lines is most 600 lines.

L.
Last edited by Lubos on Tue Jun 24, 2014 2:01 pm, edited 2 times in total.
Windows 7 Professional / Service Pack 1 - 32bit, PureBasic 5.46 LTS (x86)
My mother tongue is Czech. I have a Czech version of Windows.
Who is not afraid of GOTO, the one need not afraid any things!
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

Lubos wrote:I see that lead diskuzici about what I've actually seen not only Czech speciality. :wink:
I also did not know the demo version. But I downloaded it for testing.
Comments are calculated. Blank lines are also counted. The total number of lines is most 600 lines.

L.
Man, I hope that is not the case.
That would be mega sad.
And bad.

Continuing in the vein of my original post, I want to leverage the demo to help everyone.
Although somewhat discouraged by the lack of a definite answer so far to my simple questions, I will continue the best that I can by discussing the possible scenarios.

Case 1) 800 lines actually means 800 lines, comments don't count as program lines.
I seriously doubt it, because if it were the case then I'm confident that the demo compiler would be a much more popular tool than it is.

Case 2) 800 lines actually means 800 lines, comments count as program lines.
More likely, but again I doubt it for the aforementioned reason, I'm thinking that the compiler would be too useful and have been used. But perhaps I overestimate others.

Case 3) 800 lines really means 800 commands, comments don't count as commands.
Again more likely than the previous cases, and would present a serious challenge to produce something functionally complete and useful or fun. Challenges are good and welcomed.

Case 4) 800 lines really means 800 commands, comments count as commands.
This is the most likely implementation of the demo.
It is the configuration most hostile to anyone trying to use it to learn.

In the spirit of what I wrote in the OP, if either case 2 or 4 are in fact,
then here is my very first (feature) request to the team.

Much like you have seemingly ignored this thread, please
consider making the next version of the demo-version of the compiler ignore user comments
(And blank lines based on Lubos's post above.)
when counting the 800 lines. ;) This would help everyone involved.

Thanks in advance.
Keep it BASIC.
Lubos
Enthusiast
Enthusiast
Posts: 167
Joined: Tue Feb 03, 2004 12:32 am
Contact:

Re: 800 lines

Post by Lubos »

Here's the middle of the night. English is not my mother tongue. I would hate to offend anyone.
I have to be brief.
Example 2 is true!
Next line is possible:

Code: Select all

For i=1 To 10:Debug 10*i:Next i  ;example of possible line in PB Demo
 
(But I found 600 line as limit, not 800!)
Windows 7 Professional / Service Pack 1 - 32bit, PureBasic 5.46 LTS (x86)
My mother tongue is Czech. I have a Czech version of Windows.
Who is not afraid of GOTO, the one need not afraid any things!
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: 800 lines

Post by BorisTheOld »

Who needs an 800 line program when a one line program will work just as well? :)

It's an old DOS trick to fit large programs into small spaces:

- no comments
- 1 and 2 character variable names
- remove all unnecessary spaces

Code: Select all

OpenWindow(0,10,10,500,500,"One Line"):TextGadget(1,10,20,100,50,"Hello world!"):TextGadget(2,10,200,100,50,"This is line 1"):Repeat:E=WaitWindowEvent():If E=#PB_Event_CloseWindow:Q=1:EndIf:Until Q=1:End
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

BorisTheOld wrote:Who needs an 800 line program when a one line program will work just as well? :)

It's an old DOS trick to fit large programs into small spaces:

- no comments
- 1 and 2 character variable names
- remove all unnecessary spaces

Code: Select all

OpenWindow(0,10,10,500,500,"One Line"):TextGadget(1,10,20,100,50,"Hello world!"):TextGadget(2,10,200,100,50,"This is line 1"):Repeat:E=WaitWindowEvent():If E=#PB_Event_CloseWindow:Q=1:EndIf:Until Q=1:End
For you it's a DOS trick, however we ATARI BASIC programmers were doing it long before DOS existed.
I've seen some awesome ATARI BASIC "one liners".

My question reframed in the context of your post.
Is your PB example counted as one line or 10 'lines' by the demo-version?
At this point I'm thinking 10 'lines' instead of 1 line.

What if this book Game Programming for Teens, 3rd Edition had been written about PB instead of BB?
This is an interesting book review comment on the title above that fits well into this thread.
Keep it BASIC.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: 800 lines

Post by Demivec »

heartbone wrote:Is your PB example counted as one line or 10 'lines' by the demo-version?
At this point I'm thinking 10 'lines' instead of 1 line.
The example BorisTheOld gave is considered as one line.


Some other forum examples given for "putting as much into as few lines as possible" include the PurePunch contests. They produce cryptic but great examples. Examples were limited in one case to 80 lines of only 80 characters. If you ignored the character limit a program shown there would have only been one line (the IDE allows over a million characters on a line :!: ).

It is unfortunate that the demo counts blank lines and comments and seems to limit the line count to 600 despite it specifying an 800 line limit. I would hope that could be addressed by Fred or Freak.
Lubos
Enthusiast
Enthusiast
Posts: 167
Joined: Tue Feb 03, 2004 12:32 am
Contact:

Re: 800 lines

Post by Lubos »

Code: Select all

For i=1 To 10:Debug 10*i:Next i  ;example of possible line in PB Demo
 
Above code is one line. Therefore think: 600 lines is quite generous.

A typical way to use PureBasic on scientific and technical activities is the development of programs of size 100 - 1000 lines.
Jobs of hundreds of lines can no longer be easily programmed on a pocket calculator, but in terms of PC are still small task.
The most common purpose of these small programs is easier and more pleasant frequently repeated computing activities that would otherwise have to be carried out either by the author himself, or someone from the author's surroundings.
I wrote a book (Překvapivý_PureBasic) designed for beginners as there above examples would fit in the demo limit.
Windows 7 Professional / Service Pack 1 - 32bit, PureBasic 5.46 LTS (x86)
My mother tongue is Czech. I have a Czech version of Windows.
Who is not afraid of GOTO, the one need not afraid any things!
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

Demivec wrote:
heartbone wrote:Is your PB example counted as one line or 10 'lines' by the demo-version?
At this point I'm thinking 10 'lines' instead of 1 line.
The example BorisTheOld gave is considered as one line.


Some other forum examples given for "putting as much into as few lines as possible" include the PurePunch contests. They produce cryptic but great examples. Examples were limited in one case to 80 lines of only 80 characters. If you ignored the character limit a program shown there would have only been one line (the IDE allows over a million characters on a line :!: ).

It is unfortunate that the demo counts blank lines and comments and seems to limit the line count to 600 despite it specifying an 800 line limit. I would hope that could be addressed by Fred or Freak.
I think that 600 multiple statement lines is a lot.
Thanks for your research,Demivec. I appreciate it.
Lubos wrote:

Code: Select all

For i=1 To 10:Debug 10*i:Next i  ;example of possible line in PB Demo
 
Above code is one line. Therefore think: 600 lines is quite generous.

A typical way to use PureBasic on scientific and technical activities is the development of programs of size 100 - 1000 lines.
Jobs of hundreds of lines can no longer be easily programmed on a pocket calculator, but in terms of PC are still small task.
The most common purpose of these small programs is easier and more pleasant frequently repeated computing activities that would otherwise have to be carried out either by the author himself, or someone from the author's surroundings.
I wrote a book (Překvapivý_PureBasic) designed for beginners as there above examples would fit in the demo limit.
This is quite encouraging.
I also think that allowing 600 lines of multiple statements per line source to be compiled is very generous.
More than enough for what I want to do with the demo compiler.
Keep it BASIC.
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

Here are three more reviews of that book which fit nicely into this thread.

Lots to like, could be better, pre-teens need much guidance through it
Great for parents as well as teens
Good Book, Deceptive Marketing,

I surely hope that the development team is very busy fixing those persistent major bugs in core graphics commands in Linux,
and does not yet have time to even begin to think about this overlooked aspect of the PureBasic environment.

The more that I think about it, this activity could better handled by those in the PureBasic community who wish to advance te goal of increasing PureBasic awareness and literacy.

I'm thinking of attempting to coordinate the creation of a compendium of PureBasic goodness.
A freely available library of complete open source programs which can be run by the demo-version of the PureBasic compiler.
Back in the day a lot of people learned to program by hacking other peoples programs.

Once source code is posted to the forum without an included copyright notice, then that code is public domain.
Therefore most things to be incorporated in the compendium could be used by anyone for anything.
Sometime in the future, I imagine it could become a for sale book like the example above.
I'm thinking that Fantaisie might be the party most likely to create that physical commercialized book and CD,
or if we get lucky, DVD.
Right now I'm thinking more modestly, like a CD's worth.
Each accepted project would be a folder on the disc, a chapter in the book.
You, the program's author(s) would be responsible for the contents of the folder and chapter.
With me (and the assistant editors) and having the final say as to suitability for inclusion/exclusion.
We will of course offer helpful guidance if appropriate.

Let's see if there is enough talent, available time, and enthusiasm around here to make this happen.
I'm sure the talent is here.
Of all the programming tools that I am familiar with, only PureBasic seems advanced and flexible enough to support rapid development such as I've just demonstrated. So time really should not be much of a factor.
The variable with the most uncertainty is the interest factor.
Time will tell.
Keep it BASIC.
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: 800 lines

Post by heartbone »

(I had prepared this post before I got the good news above. Now I might be to get the full source to work with the demo compiler and have no need for stripping anything.)

SURROUND DEMO Linux x64 66 Kb
SURROUND DEMO Linux x86 61 Kb
SURROUND DEMO Windows® 32 Kb

The executable available at the link above is the result from compiling the code that I expect will conform to a 800 statement demo-version restriction, and is the sort of thing that I'd like to include in the collection.
(Based on the information that I just got, the demo is less restricted that I had earlier believed, therefore my expectations have increased. :) )
If comments are counted against the total, then I'll just have to post two versions, one commented for humans, one not for the compiler.

The executable linked above has no attached icon or included audio files, and the AI procedure was removed.
So if you want to play around with it, then you'll need two humans.
When I post the SURROUND source then I'll also post the source to the full version that I posted this morning that includes the AI (for the curious).
I think that my AI algorithm turned out well for a two hour design, I'd never even thought about it before Sunday.

If you want (custom) game sounds in the stripped version, then place three short .wav files in the run folder.
click.wav (~0.2 sec), boop.wav (~0.17 sec), die.wav (~0.6 sec)

Now that it seems possible, even probable, that I can get the full SURROUND source to compile using multiple statement lines with the demo-version!
So now I need to install that demo version so I can determine what source is acceptable.
I might even get to keep the comments in the demo compilable source.
I'll use the Windows x64 version of the compiler as the basis for compatibility.
Keep it BASIC.
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

800 lines is more than enough for simple demonstration progr

Post by heartbone »

At first the full SURROUND wouldn't compile, but after I moved a bunch of comments to the end of lines containing statements, and combined multiple statements per line where practical, I was able to reduce the source from 785 lines to 529 lines, and the entire game including most comments and the AI, compiled fine with the Windows® x64 demo-version.

I realize that the source code now looks a bit more intimidating all compacted like this, but that is the tradeoff that the people who don't have the full version of the compiler must make. Once the code hackers purchase the full compiler, then they can reformat the source to their liking.

The artificial intelligence opponent is totally contained in the procedure GETAIMOVE(). It is not very sophisticated, as I was merely putting in something that worked, hoping that the hackers will improve it and possibly submit a replacement procedure.
It does not do too well against most people, and is easy to beat, unless you play using the WRAPAROUND option where it seems to do a better job being a good opponent. The AI is not well documented as I wrote it late at night and encourage the algorithm to be replaced.

A rewarding challenge would be to replace the entire GETAIMOVE() procedure with a GETNETWORKEDMOVE() one. ;)

If you want the game to have sound, then place 3 short .wav files in the run folder named click.wav (~0.2 sec), boop.wav (~0.17 sec), die.wav (~0.6 sec).
Try these for starters: <click.wav> <boop.wav> <die.wav>

Code: Select all

; ********************************
; ******** SURROUND V1.00 ********
; ***** ELECTRONICAL SOFTWARE ****
; ******** June 24, 2014  ********
; ********************************
Global FULL
LoadFont(2,"Arial",24,#PB_Font_Bold|#PB_Font_HighQuality)
LoadFont(3,"Arial",36,#PB_Font_Bold|#PB_Font_HighQuality)
LoadFont(4,"Arial",48,#PB_Font_Bold|#PB_Font_HighQuality)
; ***********************************
; *** START OF PROCEDURES SECTION ***
; ***********************************
Procedure CLEARQUESC()
; EMPTIES XEVENT QUEUE AND RETURNS 1 WHEN ESCAPE KEY IS PRESSED
   ESCAPE= 0 : ExamineKeyboard() : If KeyboardPushed(#PB_Key_Escape) : ESCAPE= 1 : EndIf
   If Not FULL
      Repeat 
; THE "If" GETS EXECUTED WHEN USER CLICKS THE WINDOW CLOSE X ICON  
         X= WindowEvent() : If X = #PB_Event_CloseWindow : End : EndIf   
; THE UNTIL GETS SATISFIED WHEN THE QUEUE IS EMPTY
      Until X = 0   
   EndIf   
   ProcedureReturn ESCAPE
EndProcedure
Procedure.s CONDIS(SW)
; SAVED A FEW LINES BY MAKING THIS A PROCEDURE
   Select SW
      Case 0 : BUFF$= "WASD"
      Case 1 : BUFF$= "ARROW KEYS"
      Case 2 : BUFF$= "1st GAMEPAD"
      Case 3 : BUFF$= "2nd GAMEPAD"
   EndSelect 
   ProcedureReturn(BUFF$)
EndProcedure
Procedure CREATESPRITES()
; CREATE SCORING DIGITS BOTH PLAYER'S HEAD AND TRAIL SQUARES AND THE IN GAME MESSAGES.
   ClearScreen($00FFFF) : StartDrawing(ScreenOutput()) : DrawingMode(#PB_2DDrawing_Transparent) 
   DrawingFont(FontID(4)) : DrawText(0,0,"0123456789",$0000FF) : DrawText(0,70,"0123456789",$FF0000)
   DrawingFont(FontID(2)) : DrawText(116,430,"PRESS SPACE BAR TO PLAY AGAIN.",$000000)
   DrawText(116,500,"PRESS ENTER TO CHANGE OPTIONS.",$000000)
   DrawText(116,550,"PRESS SPACE BAR AGAIN TO RESUME.",$000000)
   Box(0,200,20,20,$0000FF) : Box(20,200,20,20,$7F7FFF) : Box(40,200,20,20,$FF0000)
   Box(60,200,20,20,$FF7F7F) : StopDrawing() 
   CompilerIf #PB_Compiler_OS=#PB_OS_Linux  ; COMPENSATE FOR SLIGHT FONT DIFFERENCES
      C1= 12 : C2= 82 : C3= 562 : C4= 584 : C5= 617
   CompilerElse
      C1= 14 : C2= 84 : C3= 560 : C4= 573 : C5= 611
   CompilerEndIf
   For I= 0 To 9 : GrabSprite(I+1,0+I*36,C1,36,47,#PB_Sprite_AlphaBlending)
       GrabSprite(I+11,0+I*36,C2,36,47,#PB_Sprite_AlphaBlending) : Next I
   GrabSprite(21,0,200,20,20) : GrabSprite(22,20,200,20,20) : GrabSprite(23,40,200,20,20) : GrabSprite(24,60,200,20,20)
   GrabSprite(25,117,436,C3,25) : GrabSprite(26,117,506,C4,25) : GrabSprite(27,117,556,C5,25)
   For I= 1 To 27 : TransparentSpriteColor(I,$00FFFF) : Next I
EndProcedure
Procedure DRAWSCREEN(PLYG,Array SNAR1(1),Array SNAR2(1),NPL,ACC,BLNK,NWAL,DIAG,CST,P1C,P2C,P1S,P2S)
; PLAYING, SNAKES, # PLAYERS, SPEEDUP, ERASE, WRAPAROUND, DIAGONALS, CAN START
; P1 CONTROL, P2 CONTROL, P1 SCORE, P2 SCORE
   If PLYG 
      ClearScreen($00FFFF)
; DRAW SNAKES
      If(SNAR1(0) > 1)
         For I= 2 To SNAR1(0) : DisplayTransparentSprite(22,(SNAR1(I)/100)*20,(SNAR1(I)%100)*20) : Next I
      EndIf
      If(SNAR2(0) > 1)
         For I= 2 To SNAR2(0) : DisplayTransparentSprite(24,(SNAR2(I)/100)*20,(SNAR2(I)%100)*20) : Next I
      EndIf
      DisplayTransparentSprite(21,(SNAR1(1)/100)*20,(SNAR1(1)%100)*20)
      DisplayTransparentSprite(23,(SNAR2(1)/100)*20,(SNAR2(1)%100)*20)
; DRAW SCORES
      P1S= P1S % 100 : P2S= P2S % 100
      If P1S > 9 : P1D1= (P1S/10)+ 1 : P1D2= (P1S % 10)+ 1
      Else : P1D1= (P1S % 10)+ 1 : P1D2= 0
      EndIf
      If P2S > 9 : P2D1= (P2S/10)+ 11 : P2D2= (P2S % 10)+ 11
      Else : P2D1= (P2S % 10)+ 11 : P2D2= 0
      EndIf
      DisplayTransparentSprite(P1D1,13,10,128) : If P1D2 : DisplayTransparentSprite(P1D2,53,10,128) : EndIf
      I= 0 : If P2D2 = 0 : I= 40 : EndIf
      DisplayTransparentSprite(P2D1,710+I,10,128) : If P2D2 : DisplayTransparentSprite(P2D2,750,10,128) : EndIf
      If PLYG > 1
         CompilerIf #PB_Compiler_OS=#PB_OS_Linux ; COMPENSATE FOR SLIGHT FONT DIFFERENCES
            C1= 119 : C2= 108 : C3= 92
         CompilerElse
            C1= 120 : C2= 114 : C3= 95
         CompilerEndIf
         If PLYG= 3 : DisplayTransparentSprite(25,C1,450) : DisplayTransparentSprite(26,C2,506)  ; AT GAME OVER
         ElseIf PLYG= 2 : DisplayTransparentSprite(27,C3,480) ; PAUSED
         EndIf
      EndIf
      FlipBuffers()
   Else
      ClearScreen($000000) : StartDrawing(ScreenOutput()) : DrawingFont(FontID(3))
      DrawText(260,10,"SURROUND",$FFFFFF) : DrawingFont(FontID(2))
      DrawText(20,100,"F1 -  NUMBER OF PLAYERS:  "+Str(NPL),$FFFFFF) : BUFF$= "NO" : If ACC : BUFF$= "YES" : EndIf  
      DrawText(20,150,"F2 -  SPEEDUP:  "+BUFF$,$FFFFFF) : BUFF$= "NO" : If BLNK : BUFF$= "YES" : EndIf  
      DrawText(20,200,"F3 -  ERASE:  "+BUFF$,$FFFFFF) : BUFF$= "NO" : If NWAL : BUFF$= "YES" : EndIf   
      DrawText(20,250,"F4 -  WRAPAROUND:  "+BUFF$,$FFFFFF) : BUFF$= "NO" : If DIAG : BUFF$= "YES" : EndIf  
      DrawText(20,300,"F5 -  DIAGONAL MOVES:  "+BUFF$,$FFFFFF) : BUFF$= "NO" : If Not CHSE : BUFF$= "YES" : EndIf  
      DrawText(20,350,"F6 -  PLAYER 1 CONTROLS:  "+CONDIS(P1C),$FFFFFF)
      If NPL = 2 : DrawText(20,400,"F7 -  PLAYER 2 CONTROLS:  "+CONDIS(P2C),$FFFFFF) : EndIf
      If CST Or NPL = 1 : DrawText(135,540,"PRESS THE SPACE BAR TO BEGIN",$FFFFFF) : EndIf
      StopDrawing() : FlipBuffers()               
   EndIf
EndProcedure
Procedure GETAIMOVE(CURDI,Array SNAR1(1),Array SNAR2(1),NOWALLS) 
   Dim GRID(1199)
; HERE THE AI CREATES THE MOVEMENTS (NO DIAGONALS)
   NEWDIR= 0
; BUILD OBSTRUCTION GRID
   For I= 1 To SNAR1(0) : GRID((SNAR1(I)%100)*40+(SNAR1(I)/100))= 1 : Next I
   For I= 1 To SNAR2(0) : GRID((SNAR2(I)%100)*40+(SNAR2(I)/100))= 1 : Next I
   X= SNAR2(1)/100 : Y= SNAR2(1)%100 : TX= X : TY= Y : OPT1=0: OPT2=0 : OPT3=0 : FINC= 0
   Select CURDI
      Case 0 ; UP
         Repeat 
            TY= TY-1 : If TY < 0 And NOWALLS : TY= 29 : EndIf
            If TY < 0 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT1+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0
         Repeat 
            TX= TX-1 : If TX < 0 And NOWALLS : TX= 39 : EndIf
            If TX < 0 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT2+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0 : TX= X
         Repeat 
            TX= TX+1 : If TX > 39 And NOWALLS : TX= 0 : EndIf
            If TX > 39 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT3+ 1
               EndIf
            EndIf
         Until FINC
         If OPT2 > OPT1 And OPT2 > OPT3 : NEWDIR= 4 
         ElseIf OPT3 > OPT1 And OPT3 > OPT2 : NEWDIR= 2
         ElseIf OPT3 = OPT2 And OPT2 > OPT1 : NEWDIR= 2+Random(1)*2
         EndIf             
      Case 1 ; RIGHT
         Repeat 
            TX= TX+1 : If TX > 39 And NOWALLS : TX= 0 : EndIf
            If TX > 39 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT1+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0
         Repeat 
            TY= TY-1 : If TY < 0 And NOWALLS : TY= 29 : EndIf
            If TY < 0 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT2+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0 : TY= Y
         Repeat 
            TY= TY+1 : If TY > 29 And NOWALLS : TY= 0 : EndIf
            If TY > 29 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT3+ 1
               EndIf
            EndIf
         Until FINC
         If OPT2 > OPT1 And OPT2 > OPT3 : NEWDIR= 1 
         ElseIf OPT3 > OPT1 And OPT3 > OPT2 : NEWDIR= 3
         ElseIf OPT3 = OPT2 And OPT2 > OPT1 : NEWDIR= 1+Random(1)*2
         EndIf 
      Case 2 ; DOWN
         Repeat 
            TY= TY+1 : If TY > 29 And NOWALLS : TY= 0 : EndIf
            If TY > 29 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT1+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0
         Repeat 
            TX= TX+1 : If TX > 39 And NOWALLS : TX= 0 : EndIf
            If TX > 39 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT2+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0 : TX= X
         Repeat 
            TX= TX-1 : If TX < 0 And NOWALLS : TX= 39 : EndIf
            If TX < 0 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT3+ 1
               EndIf
            EndIf
         Until FINC
         If OPT2 > OPT1 And OPT2 > OPT3 : NEWDIR= 2 
         ElseIf OPT3 > OPT1 And OPT3 > OPT2 : NEWDIR= 4
         ElseIf OPT3 = OPT2 And OPT2 > OPT1 : NEWDIR= 2+Random(1)*2
         EndIf             
      Case 3 ; LEFT
         Repeat 
            TX= TX-1 : If TX < 0 And NOWALLS : TX= 39 : EndIf
            If TX < 0 Or TX = X : FINC= 1            
            Else 
               If GRID(Y*40+TX) : FINC= 1
               Else : OPT1+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0
         Repeat 
            TY= TY+1 : If TY > 29 And NOWALLS : TY= 0 : EndIf
            If TY > 29 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT2+ 1
               EndIf
            EndIf
         Until FINC
         FINC= 0 : TY= Y
         Repeat 
            TY= TY-1 : If TY < 0 And NOWALLS : TY= 29 : EndIf
            If TY < 0 Or TY = Y : FINC= 1            
            Else 
               If GRID(TY*40+X) : FINC= 1
               Else : OPT3+ 1
               EndIf
            EndIf
         Until FINC
         If OPT2 > OPT1 And OPT2 > OPT3 : NEWDIR= 3 
         ElseIf OPT3 > OPT1 And OPT3 > OPT2 : NEWDIR= 1
         ElseIf OPT3 = OPT2 And OPT2 > OPT1 : NEWDIR= 1+Random(1)*2
         EndIf 
   EndSelect
   ProcedureReturn(NEWDIR)
EndProcedure
Procedure GETOFFKEY()
   ONKEY= 1  ; EXECUTION STAYS IN THIS PROCEDURE UNTIL USER RELEASES KEYBOARD KEYS
   Repeat
      Delay(20) : CLEARQUESC() : ExamineKeyboard() 
      If Not KeyboardPushed(#PB_Key_All) : ONKEY= 0 :EndIf         
   Until Not ONKEY
EndProcedure
Procedure UPDATESNAKE(Array SNAR(1),HPX,HPY,ERASED)
; USE COORDINATES HPX, HPY TO UPDATE THE SNAKE ARRAY. CREATE NEW HEAD @ HPX, HPY AND BUMP SNAKE LENGTH
   If Not ERASED   
      For I= SNAR(0)+1 To 2 Step -1 : SNAR(I)= SNAR(I-1) : Next I
      SNAR(0)= SNAR(0)+ 1
   EndIf
   SNAR(1)= HPX*100+HPY
   ProcedureReturn(SNAR())
EndProcedure
Procedure MAIN()
   Dim SNAKE1(600) : Dim SNAKE2(600)  ; MAX AT HALF THE 40X30 BOARD PER SNAKE
; MAIN LOOP INITIALIZATION 
   #FLAGS= #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget
   WINTITLE$= "SURROUND ~ ELECTRONICAL SOFTWARE ~ June 2014"
   FIRSTLOOP= 1  ; SET SO FIRST TIME IN MAIN LOOP WILL EXECUTE INIT SECTION
   BYEBYE= 0     ; PROGRAM WILL EXIT WHEN BYEBYE IS SET
   Repeat ; THE PROGRAM'S MAIN LOOP STARTS HERE
; TO LIMIT DISPLAY TO 50 FPS (1000/20), HOLD AT BOTTOM OF LOOP UNTIL 20 ms AFTER LOOP START
      RELEASE= ElapsedMilliseconds()+ 20
; NEXT SECTION IS EXECUTED ONLY 1ST TIME THROUGH MAIN LOOP TO SETUP I/O DEVICES 
      If FIRSTLOOP    
; PERFORM INITIALIZATION OF DEVICES  
         InitSprite()    
         CompilerIf #PB_Compiler_OS=#PB_OS_Linux
            FULL= 0 : OpenWindow(0,0,0,800,600,WINTITLE$,#FLAGS)
            OpenWindowedScreen(WindowID(0),0,0,800,600,#True,0,0)
         CompilerElse
            FULL= 1 : OpenScreen(800,600,32,"SURROUND") 
         CompilerEndIf
         InitKeyboard() : InitSound() 
         NUMJOY= InitJoystick() : JX= 0 : JY = 0 : JB0= 0 : JB1= 0
         CompilerIf #PB_Compiler_OS=#PB_OS_Linux         
; HIDES MOUSE POINTER  UNDER LINUX WINDOW
            InitMouse() : ExamineMouse() 
         CompilerEndIf   
; END DEVICE INITIALIZATIONS, NEXT LOAD USER AUDIO
         CLICK= 0 : If FileSize("click.wav") > 0  : CLICK= 1 : LoadSound(1,"click.wav") : EndIf
         BOOP= 0 : If FileSize("boop.wav") > 0 : BOOP= 1 : LoadSound(2,"boop.wav") : EndIf
         DIESO= 0 : If FileSize("die.wav") > 0 : DIESO= 1 : LoadSound(3,"die.wav") : EndIf
; CREATE SCORING DIGITS AND PLAYER'S HEAD AND TRAIL SQUARES AND IN GAME MESSAGES
         CREATESPRITES()  : GETOFFKEY()
; SHOW TITLE SCREEN FOR FIVE SECONDS. EXIT GAME IF USER PRESSES ESC KEY.
         PTRTIME= ElapsedMilliseconds()+ 5000
         Repeat 
            If CLEARQUESC() : PTRTIME= 0 : BYEBYE= 1 : EndIf   
            ExamineKeyboard() : If KeyboardPushed(#PB_Key_All) : PTRTIME= 0 : GETOFFKEY() : EndIf  
            ClearScreen($000000) : StartDrawing(ScreenOutput()) : DrawingFont(FontID(3))
            DrawText(260,265,"SURROUND",$FFFFFF) : StopDrawing() 
            For I=0 To 10 : DisplaySprite(22,180+I*40,200) : DisplaySprite(24,200+I*40,200)
               DisplaySprite(22,180+I*40,360) : DisplaySprite(24,200+I*40,360) : Next I 
            For I=0 To 3 : DisplaySprite(22,180,240+I*40) : DisplaySprite(24,600,240+I*40) : Next I
            For I=0 To 3 : DisplaySprite(24,180,220+I*40) : DisplaySprite(22,600,220+I*40) : Next I
            FlipBuffers() : Delay(100)              
         Until PTRTIME < ElapsedMilliseconds()
; INITIALIZE THE GAME SETUP INTERFACE CONTROL VARIABLES
         PLAYING= 0 : NUMP= 2 : SPEEDUP= 0 : ERASE= 0 : WRAP= 0 : DIAGONALS= 0 
         P1ID= 0 : P2ID= 1 : GOOD= 1 : FIRSTLOOP= 0
      EndIf ; FIRST INITIALIZATION LOOP END
; GATHER THIS LOOP ITERATION'S USER INPUT STATE VARIABLES FROM SYSTEM 
      ExamineKeyboard()
      If NUMJOY : ExamineJoystick(0)
         JX0= JoystickAxisX(0,0,#PB_Absolute) + JoystickAxisX(0,1,#PB_Absolute) + JoystickAxisX(0,2,#PB_Absolute)
         JY0= -JoystickAxisY(0,0,#PB_Absolute) + JoystickAxisY(0,1,#PB_Absolute) + JoystickAxisY(0,2,#PB_Absolute)
         JB0= 0 : For IND= 1 To 16 : JB0= JB0+ JoystickButton(0,IND) : Next IND 
         If NUMJOY > 1 : ExamineJoystick(1)
            JX1= JoystickAxisX(1,0,#PB_Absolute) + JoystickAxisX(1,1,#PB_Absolute) + JoystickAxisX(1,2,#PB_Absolute)
            JY1= -JoystickAxisY(1,0,#PB_Absolute) + JoystickAxisY(1,1,#PB_Absolute) + JoystickAxisY(1,2,#PB_Absolute)
            JB1= 0 : For IND= 1 To 16 : JB1= JB1+ JoystickButton(1,IND) : Next IND 
         EndIf
      EndIf          
      If KeyboardPushed(#PB_Key_Escape) : BYEBYE+ 1 : If CLICK : PlaySound(1) : Delay(100) : EndIf
      EndIf  ; EXIT PROGRAM UNCONDITIONALLY WHEN USER PRESSES ESCAPE   
; PROCESS USER INPUT (OTHER THAN ESCAPE) SECTION           
      If PLAYING = 1 Or PLAYING = 2  ; IF PLAYING GAME OR PAUSED GAME
         If KeyboardPushed(#PB_Key_Space) : If CLICK : PlaySound(1) : EndIf
            PLAYING= 3- PLAYING  : GETOFFKEY() ; TOGGLE PAUSE
         EndIf
         ALREADY= NEWDIR1+ NEWDIR2 : UP= 0 : RIGHT= 0 : DOWN= 0 : LEFT= 0  ; HERE SENSE THE ARROW KEYS WHILE PLAYING
If ((KeyboardPushed(#PB_Key_W) And P1ID=0) Or (KeyboardPushed(#PB_Key_Up) And P1ID=1) Or (JY0=1 And P1ID=2) Or (JY1=1 And P1ID=3)) : UP= 1 : EndIf
If ((KeyboardPushed(#PB_Key_D) And P1ID=0) Or (KeyboardPushed(#PB_Key_Right) And P1ID=1) Or (JX0=1 And P1ID=2) Or (JX1=1 And P1ID=3)) : RIGHT= 1 : EndIf
If ((KeyboardPushed(#PB_Key_S) And P1ID=0) Or (KeyboardPushed(#PB_Key_Down) And P1ID=1) Or (JY0=-1 And P1ID=2) Or (JY1=-1 And P1ID=3)) : DOWN= 1 : EndIf
If ((KeyboardPushed(#PB_Key_A) And P1ID=0) Or (KeyboardPushed(#PB_Key_Left) And P1ID=1) Or (JX0=-1 And P1ID=2) Or (JX1=-1 And P1ID=3)) : LEFT= 1 : EndIf
         If DIAGONALS
            If UP And RIGHT : If CURDIR1<>4 And CURDIR1<>6 : NEWDIR1= 5 : EndIf
            ElseIf RIGHT And DOWN : If CURDIR1<>5 And CURDIR1<>7 : NEWDIR1= 6 : EndIf
            ElseIf DOWN And LEFT : If CURDIR1<>4 And CURDIR1<>6 : NEWDIR1= 7 : EndIf
            ElseIf LEFT And UP : If CURDIR1<>5 And CURDIR1<>7 : NEWDIR1= 8 : EndIf
            ElseIf UP And CURDIR1<> 0 And CURDIR1 <> 2 : NEWDIR1= 1
            ElseIf RIGHT And CURDIR1<> 1 And CURDIR1 <> 3 : NEWDIR1= 2
            ElseIf DOWN And CURDIR1<> 0 And CURDIR1 <> 2 : NEWDIR1= 3
            ElseIf LEFT And CURDIR1<> 1 And CURDIR1 <> 3 : NEWDIR1= 4
            EndIf
         Else
            If UP And (CURDIR1=3 Or CURDIR1=1) : NEWDIR1= 1 
            ElseIf RIGHT And (CURDIR1=0 Or CURDIR1=2) : NEWDIR1= 2 
            ElseIf DOWN And (CURDIR1=3 Or CURDIR1=1) : NEWDIR1= 3 
            ElseIf LEFT And (CURDIR1=0 Or CURDIR1=2) : NEWDIR1= 4 
            EndIf
         EndIf
         If NUMP = 2 : UP= 0 : RIGHT= 0 : DOWN= 0 : LEFT= 0 
If ((KeyboardPushed(#PB_Key_W) And P2ID=0) Or (KeyboardPushed(#PB_Key_Up) And P2ID=1) Or (JY0=1 And P2ID=2) Or (JY1=1 And P2ID=3)) : UP= 1 : EndIf
If ((KeyboardPushed(#PB_Key_D) And P2ID=0) Or (KeyboardPushed(#PB_Key_Right) And P2ID=1) Or (JX0=1 And P2ID=2) Or (JX1=1 And P2ID=3)) : RIGHT= 1 : EndIf
If ((KeyboardPushed(#PB_Key_S) And P2ID=0) Or (KeyboardPushed(#PB_Key_Down) And P2ID=1) Or (JY0=-1 And P2ID=2) Or (JY1=-1 And P2ID=3)) : DOWN= 1 : EndIf
If ((KeyboardPushed(#PB_Key_A) And P2ID=0) Or (KeyboardPushed(#PB_Key_Left) And P2ID=1) Or (JX0=-1 And P2ID=2) Or (JX1=-1 And P2ID=3)) : LEFT= 1 : EndIf 
            If DIAGONALS
               If UP And RIGHT : If CURDIR2<>4 And CURDIR2<>6 : NEWDIR2= 5 : EndIf
               ElseIf RIGHT And DOWN : If CURDIR2<>5 And CURDIR2<>7 : NEWDIR2= 6 : EndIf
               ElseIf DOWN And LEFT : If CURDIR2<>4 And CURDIR2<>6 : NEWDIR2= 7 : EndIf
               ElseIf LEFT And UP : If CURDIR2<>5 And CURDIR2<>7 : NEWDIR2= 8 : EndIf
               ElseIf UP And CURDIR2<> 0 And CURDIR2 <> 2 : NEWDIR2= 1
               ElseIf RIGHT And CURDIR2<> 1 And CURDIR2 <> 3 : NEWDIR2= 2
               ElseIf DOWN And CURDIR2<> 0 And CURDIR2 <> 2 : NEWDIR2= 3
               ElseIf LEFT And CURDIR2<> 1 And CURDIR2 <> 3 : NEWDIR2= 4
               EndIf
            Else
               If UP And (CURDIR2=3 Or CURDIR2=1) : NEWDIR2= 1 
               ElseIf RIGHT And (CURDIR2=0 Or CURDIR2=2) : NEWDIR2= 2 
               ElseIf DOWN And (CURDIR2=3 Or CURDIR2=1) : NEWDIR2= 3 
               ElseIf LEFT And (CURDIR2=0 Or CURDIR2=2) : NEWDIR2= 4
               EndIf
            EndIf
         Else
            NEWDIR2= GETAIMOVE(CURDIR2,SNAKE1(),SNAKE2(),WRAP) ; HERE THE AI CREATES THE MOVEMENTS (NO DIAGONALS)
         EndIf
         If (NEWDIR1 Or NEWDIR2) And Not ALREADY And CLICK : PlaySound(1) : EndIf         
      Else  ; NOT YET PLAYING, INSTEAD PROCESSING FRONTEND KEYBOARD INPUT 
         If PLAYING = 3 
            If KeyboardPushed(#PB_Key_Space) : If CLICK : PlaySound(1) : EndIf
               Goto RESTART
            ElseIf KeyboardPushed(#PB_Key_Return) : PLAYING= 0 : If CLICK : PlaySound(1) : EndIf
               GETOFFKEY()
            EndIf
         Else
            If ((KeyboardPushed(#PB_Key_RightAlt) Or KeyboardPushed(#PB_Key_LeftAlt)) And KeyboardPushed(#PB_Key_Return)) Or KeyboardPushed(#PB_Key_F) Or KeyboardPushed(#PB_Key_S) Or KeyboardPushed(#PB_Key_W)
               If CLICK : PlaySound(1) : EndIf  ; F, S, W, OR Alt+Enter TO TOGGLE FULLSCRFEEN 
               GETOFFKEY()
               CompilerIf #PB_Compiler_OS=#PB_OS_Windows
                  CloseScreen()
                  If Not FULL : CloseWindow(0) : FULL= 1 : OpenScreen(800,600,32,"SURROUND")
                  Else : FULL= 0 : OpenWindow(0,0,0,800,600,WINTITLE$,#FLAGS)
                     OpenWindowedScreen(WindowID(0),0,0,800,600,#True,0,0) : CLEARQUESC()
                  EndIf
                  CREATESPRITES()  ; MUST RECREATE SCORING DIGITS AND PLAYER'S HEAD AND TRAIL SQUARES
               CompilerEndIf
            ElseIf KeyboardPushed(#PB_Key_F1) : If CLICK : PlaySound(1) : EndIf
               NUMP= 3- NUMP : GETOFFKEY() : If NUMP= 1 : DIAGONALS= 0 : EndIf
            ElseIf KeyboardPushed(#PB_Key_F2) : If CLICK : PlaySound(1) : EndIf
               SPEEDUP= 1- SPEEDUP : GETOFFKEY()
            ElseIf KeyboardPushed(#PB_Key_F3) : If CLICK : PlaySound(1) : EndIf
               ERASE= 1- ERASE : GETOFFKEY()
            ElseIf KeyboardPushed(#PB_Key_F4) : If CLICK : PlaySound(1) : EndIf
               WRAP= 1- WRAP : GETOFFKEY()
            ElseIf KeyboardPushed(#PB_Key_F5) And NUMP = 2: If CLICK : PlaySound(1) : EndIf
               DIAGONALS= 1- DIAGONALS : GETOFFKEY()
            ElseIf KeyboardPushed(#PB_Key_F6) : If CLICK : PlaySound(1) : EndIf
               P1ID= P1ID+ 1 : If (P1ID = 2 And NUMJOY = 0) Or (P1ID = 3 And NUMJOY < 2) Or P1ID= 4 : P1ID= 0 : EndIf
               GETOFFKEY() : If P1ID = P2ID : GOOD= 0 
               Else : GOOD= 1 : EndIf
            ElseIf KeyboardPushed(#PB_Key_F7) And NUMP = 2 : If CLICK : PlaySound(1) : EndIf
               P2ID= P2ID+ 1 : If (P2ID = 2 And NUMJOY = 0) Or (P2ID = 3 And NUMJOY < 2) Or P2ID= 4 : P2ID= 0 : EndIf
               GETOFFKEY() : If P1ID = P2ID : GOOD= 0 
               Else : GOOD= 1 : EndIf            
            ElseIf KeyboardPushed(#PB_Key_Space) And ((GOOD And NUMP=2) Or NUMP=1) : If CLICK : PlaySound(1) : EndIf
; CHECK FOR START OF GAME, PLAYING<>0 SIGNALS IN GAME         
RESTART: :     PLAYING= 1 : P1S= 0 : P2S= 0 : GETOFFKEY()
NEXTPOINT: :   P1DEAD= 0 : P2DEAD= 0 : NEWDIR1= 0 : NEWDIR2= 0 
               SNAKE1(0)= 1 ; CREATE INITIAL SNAKES. SNAKE(0)= LENGTH OF SNAKE, SNAKE(>0) = X{0-39}*100+ Y{0-29} 
               CURDIR1= 1 : DX1= 1 : DY1= 0 : HP1X= 9 : HP1Y= 15 : SNAKE1(1)= HP1X*100+ HP1Y
               SNAKE2(0)= 1 : CURDIR2= 3 : DX2= -1 : DY2= 0 : HP2X= 30 : HP2Y= 15 : SNAKE2(1)= HP2X*100+ HP2Y        
; SET INITIAL MOVE SPEED. IF SPEEDUP IS SET, THEN USE VELCHGTIM AS TIMER FOR NEXT APPLICATION OF SPINC
               SPEED= 330 : SPINC= -60 : VELCHGTIM= 20000
; ATLIMIT GETS SET TO 1 WHEN SPEED INCREASE IS AT MAXIMUM, SET NEXT SPEED CHANGE TIME, SET NEXT SNAKE MOVE TIME
               ATLIMIT= 0 : NEXSPC= ElapsedMilliseconds()+ VELCHGTIM : NEXMOV= ElapsedMilliseconds()+ SPEED
            EndIf 
         EndIf
      EndIf      
; FINISHED GATHERING AND PROCESSING USER INPUT, NEXT PROCESS THE CONTEXTUAL AND TIMED EVENTS       
      CLEARQUESC()    ; EMPTY EVENT QUEUE ONE LAST TIME BEFORE GRAPHICS CONSTRUCTION
; CREATE SCREEN BASED ON PARAMETERIZED STATE VARIABLES 
      DRAWSCREEN(PLAYING,SNAKE1(),SNAKE2(),NUMP,SPEEDUP,ERASE,WRAP,DIAGONALS,GOOD,P1ID,P2ID,P1S,P2S) 
      If ElapsedMilliseconds() > NEXMOV And PLAYING = 1 And Not (P1DEAD Or P2DEAD) ; IS TIME TO MOVE SNAKES?
         If NEWDIR1 : CURDIR1= NEWDIR1-1 : NEWDIR1= 0 : EndIf
         Select CURDIR1  ; CALCULATE NEXT SNAKE 1 HEAD POSITION.
            Case 0 : DX= 0 : DY= -1 ; GOING UP
            Case 1 : DX= 1 : DY= 0 ; RIGHT
            Case 2 : DX= 0 : DY= 1 ; DOWN
            Case 3 : DX= -1 : DY= 0 ; LEFT
            Case 4 : DX= 1 : DY= -1 ; NE
            Case 5 : DX= 1 : DY= 1 ; SE
            Case 6 : DX= -1 : DY= 1 ; SW
            Case 7 : DX= -1 : DY= -1 ; NW
         EndSelect
         HP1X= HP1X+ DX : HP1Y= HP1Y+ DY
         If WRAP
            If HP1X<0 : HP1X= 39 
            ElseIf HP1X > 39 : HP1X= 0 : EndIf
            If HP1Y<0 : HP1Y= 29 
            ElseIf HP1Y > 29 : HP1Y= 0 : EndIf
         Else 
            If HP1X<0 Or HP1X=40 Or HP1Y<0 Or HP1Y=30 : P1DEAD= 1 : P2S+ 1 : EndIf
         EndIf
         If NEWDIR2 : CURDIR2= NEWDIR2-1 : NEWDIR2= 0 : EndIf
         Select CURDIR2  ; CALCULATE NEXT SNAKE 2 HEAD POSITION
            Case 0 : DX= 0 : DY= -1 ; GOING UP
            Case 1 : DX= 1 : DY= 0 ; RIGHT
            Case 2 : DX= 0 : DY= 1 ; DOWN
            Case 3 : DX= -1 : DY= 0 ; LEFT
            Case 4 : DX= 1 : DY= -1  ; NE
            Case 5 : DX= 1 : DY= 1  ; SE
            Case 6 : DX= -1 : DY= 1 ; SW
            Case 7 : DX= -1 : DY= -1 ; NW
         EndSelect
         HP2X= HP2X+ DX : HP2Y= HP2Y+ DY
         If WRAP
            If HP2X<0 : HP2X= 39 
            ElseIf HP2X > 39 : HP2X= 0 : EndIf
            If HP2Y<0 : HP2Y= 29 
            ElseIf HP2Y > 29 : HP2Y= 0 : EndIf
         Else 
            If HP2X<0 Or HP2X=40 Or HP2Y<0 Or HP2Y=30 : P2DEAD= 1 : P1S+ 1 : EndIf
         EndIf
         For IND= 1 To SNAKE1(0) ; CHECK FOR ANY SNAKE HITTING ITSELF OR ANOTHER
            If SNAKE1(IND)/100=HP1X And SNAKE1(IND)%100=HP1Y : P1DEAD= 1 : P2S+ 1 : EndIf         
            If SNAKE1(IND)/100=HP2X And SNAKE1(IND)%100=HP2Y : P2DEAD= 1 : P1S+ 1 : EndIf                
         Next IND
         For IND= 1 To SNAKE2(0)  
            If SNAKE2(IND)/100=HP1X And SNAKE2(IND)%100=HP1Y : P1DEAD= 1 : P2S+ 1 : EndIf         
            If SNAKE2(IND)/100=HP2X And SNAKE2(IND)%100=HP2Y : P2DEAD= 1 : P1S+ 1 : EndIf            
         Next IND         
         BLANK= 0
         If ERASE And ((P1ID=0 And KeyboardPushed(#PB_Key_LeftControl)) Or (P1ID=1 And KeyboardPushed(#PB_Key_RightControl)) Or (P1ID=2 And JB0) Or(P1ID=3 And JB1))
            BLANK= 1
         EndIf 
         UPDATESNAKE(SNAKE1(),HP1X,HP1Y,BLANK) : BLANK= 0
         If ERASE And ((P2ID=0 And KeyboardPushed(#PB_Key_LeftControl)) Or (P2ID=1 And KeyboardPushed(#PB_Key_RightControl)) Or (P2ID=2 And JB0) Or(P2ID=3 And JB1))
            BLANK= 1
         EndIf
         UPDATESNAKE(SNAKE2(),HP2X,HP2Y,BLANK)  
         If P1DEAD Or P2DEAD
            CLEARQUESC()        
            DRAWSCREEN(PLAYING,SNAKE1(),SNAKE2(),NUMP,SPEEDUP,ERASE,WRAP,DIAGONALS,GOOD,P1ID,P2ID,P1S,P2S) 
            If DIESO : PlaySound(3) : EndIf
            Delay(1000) : CLEARQUESC()
            If ((P1S > 9) Or (P2S > 9)) And (P1S <> P2S)
               PLAYING= 3 : GETOFFKEY() 
            Else
               Goto NEXTPOINT
            EndIf
         EndIf 
         If BOOP : PlaySound(2) : EndIf
         NEXMOV= ElapsedMilliseconds()+ SPEED
      EndIf
      If SPEEDUP And PLAYING = 1 And Not (P1DEAD Or P2DEAD) And Not ATLIMIT
         If ElapsedMilliseconds() > NEXSPC  ; CHECK IF TIME TO UPDATE SNAKE SPEED 
            NEXSPC= ElapsedMilliseconds()+ VELCHGTIM
            SPEED= SPEED+ SPINC
            If SPEED = 30 : ATLIMIT= 1 : EndIf
         EndIf
      EndIf     
      If ElapsedMilliseconds() < RELEASE ; LIMITS FPS TO 50 MAX 
         Repeat : Delay(2) : Until ElapsedMilliseconds() > RELEASE
      EndIf
   Until BYEBYE  
EndProcedure ;(MAIN)
; ***********************************
; **** END OF PROCEDURES SECTION ****
; ***********************************
; PROGRAM'S GLOBAL ENVIRONMENT RESOURCE SETUP IS FINISHED, CONTINUE EXECUTION.
MAIN()
End
Robust error checking was the first thing to go, but with a program this simple and closed, it causes no major problems.
There are no Macs in my world, so if you have one this source will undoubtedly need changing.
Keep it BASIC.
Post Reply