• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

Programmierwettbewerb 2: Aaah a snake!

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.122
Ort
in der Zukunft
Kannst ja eine minified_js erstellen ;)
Die kommentierte hilft halt denen die draus lernen sollen / wollen enorm.
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
pff nokia, mein erstes snake lief auf einem TI-83 (der uralte mit 32k) in assembler-sprache (nein, das hab ich als 14-jähriger nicht selbst geschrieben ;))...

brainfuck, anyone? :D

naja, wenn wir schon bei exotischen sprachen sind, ich schmeiß mal mein labview an *duck* - die ausgabe kann wahlweise auf dem monitor oder auf einem 3D-drucker erfolgen :D...
 

Kugelfisch

Nerd

Registriert
12 Juli 2013
Beiträge
2.342
Ort
Im Ozean
Ursprünglich vor längerer Zeit für einen anderen Wettbewerb entwickelt, deshalb ausser Konkurrenz - aber hier wohl nicht ganz unpassend, wenn auch die `Code ist gut zu kommentieren`-Regel nicht eingehalten wurde. Der Funktionsumfang ist beschränkt, weil die Code-Grösse auf 10 Zeilen mit 120 Zeichen begrenzt war ...
[src=perl]use Term::ReadKey;sub k{return ReadKey(-1)};sub ak{$k='';$k.=$c while($c=k());return $k;};ReadMode 5;$|=1; print "\ec".
"\e[2J\e[?25l\e[?7l\e[1;1H\e[0;0r\e[4242;4242H\e[6n";($s.=$c)until(($c=k())eq'R');$s=~s/[^0-9;]//g;($h,$w)=split(/;/,$s
);print("\e[2;1H\e[34m\e[40m".('#'x$w)."\r\n".(('#'.(' 'x($w-2))."#\r\n")x($h-3)).('#'x$w)."\e[2;1H\e[0m");$pt=0;sub mt
{$_=q(=#'64$"5&% ^/",&);tr/!-=^_/`-{OS/;print("\e[1;1H\e[44;97m $_".(' 'x$w)."\e[1;".($w-8-int(log($pt+0.1)/log(10))).
"H\e[44;97mScore: $pt");}sub pp{do{(@b=(int(rand($h-3))+3,int(rand($w-2))+2))}while($f[$b[0]][$b[1]]);$f[$b[0]][$b[1]]=
42;print("\e[".join(';',@b)."H\e[40;91m*");}@p=(int($h/2),int($w/2));$d=0;@f=([]);mt();pp()for(0..10);while($p[0]>2&&$p
[0]<$h&&$p[1]>1&&$p[1]<$w){$k=ak();last if($k=~/q/);$d=$k-0x41 if(($k=ord(substr($k,2,1)))&&(int(($k-0x41)/2)!=int($d/2
)));$p[int($d/2)]-=(($d%2)*2-1)*(int($d/2)*2-1);if($f[$p[0]][$p[1]]==42){pp();$pt++;mt();};last if($f[$p[0]][$p[1]]==23
);$f[$p[0]][$p[1]]=23;print("\e[".join(';',@p)."H\e[103m ");select(undef,undef,undef,($ww=(+0.2-$pt/200))>0.01?$ww:0.01
);}print "\e[".join(';',@p)."H\e[5;41;97mX";sleep(5);ReadMode 0;print"\ec";#ONLY_PERL_CAN_PARSE_PERL_SO_RUN_ME_IN_PERL#[/src]
 
Zuletzt bearbeitet:

Kugelfisch

Nerd

Registriert
12 Juli 2013
Beiträge
2.342
Ort
Im Ozean
Beachte den einzigen Kommentar am Ende des Codes (falls Zweifel bestehen - ja, das ist gültiger Perl-Code). Zur Ausführung wird perl sowie Term::ReadKey und ein VT100-kompatibles Terminal benötigt.

Nachtrag: Ursprünglich habe ich das übrigens für einen Wettbewerb entwickelt, bei welchem ein Programm in max. 10 Zeilen Code ausschliesslich unter Verwendung einiger Standardbibliotheken entwickelt werden sollte. Funktionsumfang und Zweck waren nicht vorgegeben, Idee und Funktionsumfang der Implementierung flossen in die Bewertung ein.
 
Zuletzt bearbeitet:

TheSniperFan

Neu angemeldet

Registriert
15 Juli 2013
Beiträge
363
Ort
/dev/random
@Kugelfisch: Ein Wort: Fett. :eek:

@Larius: Okay, macht Sinn. Ich programmiere im Moment ohnehin noch in einem privaten Bitbucket Repository von mir und werde die Kommentare dort auf englisch lassen damit es Einheitlich ist. Ins Wettbewerbs-Repository kommt dann eine übersetzte Version.

Bis zum 8. November ist noch viel Zeit und mein Grundgerüst steht quasi schon (inklusive Gameloop mit momentan PC Masterrace-tauglichen 200.000 fps :D).
 

theSplit

1998
Teammitglied

Registriert
3 Aug. 2014
Beiträge
28.012
Ich hab mich mal mit meinen Github Credentials bei Gitlab angemeldet und meinen Account als Master für das theSplit Projekt in NGB-Snake-theSplit gesetzt... wollte nur bescheid geben, nicht das sich jemand wundert... hoffe das ist ok. :)

Im übrigen habe ich nun folgende Email von Github übernehmen lassen in Gitlab: ich @ users.noreply.github.com - und die kann man bei Github einstellen wenn man seine Email "verstecken" möchte, was auch von Gitlab akzeptiert wird wenn man sich mit Github dort anmeldet.
Ich wollte das nur mal erwähnen da es praktisch ist wenn man schon einen Github Account hat und dann auch mit einem eigenen Account arbeiten möchte. Man hat aber auch die zusätzlich Option noch eine andere Email mit anzugeben bzw. als Hauptemail nachträglich bei Gitlab zu setzen, wenn gewünscht.
 

accC

gesperrt

Registriert
14 Juli 2013
Beiträge
5.250
@Kugelfisch Okay, das ist wirklich klein. Und ich dachte mit ca 6kb bin ich gut.. Wahrscheinlich ließe sich mit ein wenig Optimierung noch das ein oder andere KB sparen, triviales Komprimieren bringt schon mal 1,95KB, für mehr müsste ich die Textausgabe verkleinern und Funktionen noch sparender schreiben.
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
der erste entwurf ist fertig:

labsnake.png

Anhang anzeigen LabSnake.zip
die exe ist beschauliche 242kb klein geworden (inkl. icon), aber wer kein labview 2014 installiert hat (wahrscheinlich niemand), muss vorher die klitzekleine 270MB große runtime engine installieren :D...

wenn mir jemand die zugangsdaten gibt, kann ich den sourcecode auch in das git-dingens hochladen...

funktionen:
- normales snake (ca. die erste hälfte der "schwierigkeits-level")
- die schlange wird nicht mit der zeit schneller (finde ich doof, den schwierigkeitsgrad macht ja die wachsende länge aus), kann man aber simpel nachrüsten
- die geschwindigkeit lässt sich anpassen, auch während des spiels (bescheiß-funktion)
- leertaste pausiert das spiel (bescheiß-funktion)
- es gibt einen buffer für die letzten 3 pfeiltasten-eingaben, das erleichtert schnelle 180°-turns, weil man sie innerhalb eines frames eingeben kann - die schlange arbeitet dann den buffer in den nächsten frames ab (halte ich nicht für bescheißen, sondern für ease-of-use :D)
- es werden nur die beiden jeweiligen abbiege-eingaben akzeptiert (z.b. hoch/runter, wenn die schlange gerade horizontal ist), d.h. eingaben, die die schlange sofort um 180° in sich selbst umkehren (was zur kollision führt) werden rausgefiltert
- sobald die schlange das ganze spielfeld füllt, hat man gewonnen (viel spaß :D)

todo:
- zufällige bonusfelder, die mehr punkte bringen und die schlange nicht verlängern (finde ich nicht extrem sinnvoll, aber wäre einfach einzubauen)
- bitmap-grafiken statt vollfarb-"pixel"

die anderen späßchen (verschieden geformte levels, skalierbares feld) sind zuviel arbeit für einen abend, zumindest wenn man alles kommentieren muss.. außerdem ist ein während des spiels skalierbares feld nicht wirklich sinnvoll, weil sich dann ggf. die schlange oder der rote futter-block auf einmal außerhalb des felds befindet.. möglich wäre es z.b. die spielfeldgröße per ini-datei beim programmstart festzulegen (wäre etwas gepfusche mit den UI-elementen, aber machbar)...
 

Brother John

(schein)heilig

Registriert
1 Aug. 2013
Beiträge
235
Ahh, das gute alte Snake. :) Ich mach mit!

Und direkt schonmal außer Konkurrenz, weil 1999 entstanden: Hungry Worms.

hungry-worms.png
https://bitbucket.org/BrotherJohn/hungry-worms/downloads

War mein erstes ernsthaftes Programmierprojekt. QuickBASIC, 3000 Zeilen Spiel + 1700 Zeilen Leveleditor. Also eine gewaltige Codebase. :D Dachte ich zumindest damals. Läuft mit DOSBox immer noch einwandfrei.

@Novgorod
Gibts ne Möglichkeit, in den Quellcode sinnvoll reinzuschauen, ohne sich gleich LabVIEW zu besorgen?
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
@Brother John: hm, ich kenne zumindest keinen "source-viewer", aber ich werde mich mal umschauen.. ich kann zwar screenshots machen, aber ab einer gewissen komplexität wird's zu verschachtelt (das ist ja gerade der witz an "G") und man bräuchte zig screenshots um alles abzudecken.. außerdem erkennt man allein vom screenshot (d.h. ohne editor und kontexthilfe/inspektorfunktion) nicht alle datentypen und kann auch nicht in die properties von UI-elementen schauen.. wenn's hilft, kann ich den source in eine frühere version konvertieren (aber nur bis LV 2012, sonst würden funktionen fehlen)..

--- [2015-08-22 23:00 CEST] Automatisch zusammengeführter Beitrag ---

es scheint zumindest keinen offiziellen source viewer zu geben - das liegt wohl an der mangelnden nachfrage, weil jemand, der den code versteht, in der regel selbst zugang zur developement-version hat..

ich hab allerdings ein kleines tool gefunden, das das "screenshot machen" automatisiert und alles in eine flash-datei reinquetscht, so dass man zumindest den kompletten code durchsehen kann:
Anhang anzeigen labsnake_source.zip

einfach oben links aufs blockdiagramm-symbol klicken.. navigieren kann man durch klicken+ziehen (wie google maps) und die verschachtelten fenster kann man durch die entsprechenden pfeilsymbole durchschalten - allerdings sind die drop-down-menüs nicht nutzbar und man sieht die datentypen nicht (außer grob anhand der wires).. und ja, ich weiß, die dokumentation ist recht dürftig :D...
 

sharpy35

Neu angemeldet

Registriert
13 Apr. 2015
Beiträge
210
Ich setze es in JavaScript, HTML, CSS und Canvas um :D *hr hr* Schön old school :D Bin auch schon fast fertig ^^
 

theSplit

1998
Teammitglied

Registriert
3 Aug. 2014
Beiträge
28.012
Was seid ihr denn alle so schnell? :eek:

Ich mach gemütlich, sind ja noch gute 2,5 Monate bis zum Wettbewerbs Ende.... ich alter Sack lass mich doch nicht von euch "Jungspunden" hetzen ;) :D
 

exomo

NGBler

Registriert
1 Aug. 2015
Beiträge
129
Finde ich einen tollen Wettbewerb / Herausforderung. Da habe ich auf jeden Fall Lust mich mal an einer Schlange zu versuchen. Ich wollte sowieso mal wieder was mit Grafik und so machen. Ob ich die Zeit dafür finde weiß ich aber noch nicht.
Ich werde auf jeden Fall was mit C++ machen, vermutlich Grafik/Sound mit SFML (falls das erlaubt ist, aber ich hätte wenig Lust jedes Pixel zu Hand in eine Windows Form zu zeichnen)

@Brother John: Deine Hungrigen Würmer sehen ein bisschen nach "Nibbles" aus, du hast doch nicht etwa das Design ein bisschen abgekupfert :D

Ich hätte noch eine Snake Variante für ein kleines Mikrocontroller-Board mit Display auf Lager. Es heißt ja der Code muss nicht Multi-Plattform sein, ;-).
 

sharpy35

Neu angemeldet

Registriert
13 Apr. 2015
Beiträge
210
So was ich bisher habe:

[src=html5]
<!DOCTYPE html>
<html>
<head>
<title>Snake</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="core.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div class="header">Snake - by Sharpy35</div>
<canvas id="canvas" width="450" height="450"></canvas>

<span id="gamestatus">Gestartet</span>
Punkte: <span class="points">0</span>

</body>

</html>
[/src]

[src=javascript]
$(document).ready(function(){

var droppedSnakePartX = 0;
var droppedSnakePartY = 0;
var lastDirection = "right";
var canvas;
var snake;
var context;
var interval;
var points = 0;

$(window).keydown(function(e) {

switch (e.keyCode)
{
case 27: //escape
pause_game();
break;
case 32: // Space
resume_game();
break;
case 37: //Left
move_snake("left");
break;
case 38: //Up
move_snake("up");
break;
case 39: // right
move_snake("right");
break;
case 40: //down
move_snake("down");
break;
default:
// do nothing
break;
}
});

/**
* Pausiert das Spiel mit Escape
*/
function pause_game()
{
$("#gamestatus").html("Pause");
clearInterval(interval);
}

/**
* Lässt das Spiel mit Leertaste Weiterlaufen
*/
function resume_game()
{
$("#gamestatus").html("Geht weiter");
interval = window.setInterval(function(){
move_snake();
}, 100);
}

/**
* represents a snakepart
*
* @param x
* @param y
* @param width
* @param height
* @param fill
* @constructor
*/
function SnakePart(x, y, width, height, fill)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.fill = fill;
this.prevX = 0;
this.prevY = 0;
}


/**
* Setzt die neuen Koordinateneines Elements und bewegt die Schlange
*
* @param direction
*/
function move_snake(direction)
{
if (direction == undefined) {
direction = lastDirection;
}


for (var i = 0; i < snake.length; i++) {

snake.prevX = snake.x;
snake.prevY = snake.y;

if (i == 0) {

switch(direction)
{
case "right":

snake.x = snake.x + 10;
lastDirection = "right";
break;
case "left":

snake.x = snake.x - 10;
lastDirection = "left";
break;
case "up":

snake.y = snake.y - 10;
lastDirection = "up";
break;
case "down":

snake.y = snake.y + 10;
lastDirection = "down";
break;
default:
//do nothing
break;
}

// dropped snake part was guzzled
if (snake.x == droppedSnakePartX && snake.y == droppedSnakePartY) {

var lastSnakePart = snake.length - 1;

snake.push(new SnakePart(snake[lastSnakePart].x, snake[lastSnakePart].y, 10, 10));
addPoints(10);
$('.points').html(points);
var numberCounter = $(".counter-number");
score = parseInt(numberCounter.html()) + 1;
numberCounter.html(score);

dropRandomSnakeparts();
}


} else {

snake.x = snake[i - 1].prevX;
snake.y = snake[i - 1].prevY;
}


draw_snake();
}

detectCollision();
}

/**
* Ermittelt ob die Schlange auf die Wand oder sich selbst trifft
*/
function detectCollision()
{
if (snake[0].x == canvas.width || snake[0].y == canvas.height
|| snake[0].x < 0 || snake[0].y < 0)
{
restart();
}

for (var i = 1; i < snake.length; i++) {
if(snake[0].x == snake.x && snake[0].y == snake.y) {
restart();
break;
}
}
}

/**
* Startet das Spiel neu
*/
function restart()
{
alert("Das Spiel ist vorbei.");
location.reload();
}

/**
* Malt ein Element einer Schlange.
*/
function draw_snake()
{
context.clearRect(0,0,canvas.width, canvas.height);

for (var i = 0; i < snake.length; i++) {
context.fillStyle = snake.fill;
context.fill();
context.fillRect(snake.x, snake.y, snake.width, snake.height);
}

// Da das gedroppte SnakePart Element bei jedem neuzeichnen sichtbar sein soll muss es hier nochmal gerendert werden.
context.fillStyle = "red";
context.fill();
context.fillRect(droppedSnakePartX, droppedSnakePartY, 10, 10);

}

/**
* Wirft zufällige SnakeParts ab die von der Schlange gefressen werden können.
*/
function dropRandomSnakeparts()
{
var w = canvas.width;
var h = canvas.height;

droppedSnakePartX = randomNumber(0,w);
droppedSnakePartY = randomNumber(0,h);

var restX = droppedSnakePartX % 10;
var restY = droppedSnakePartY % 10;

droppedSnakePartX -= restX;
droppedSnakePartY -= restY;

while(checkIfSnakePartIsDroppedOnSnake(droppedSnakePartX, droppedSnakePartY)) {
dropRandomSnakeparts();
}

context.fillStyle = "red";
context.fill();
context.fillRect(droppedSnakePartX, droppedSnakePartY, 10, 10);
}

/**
* Fügt neue Punkte hinzu wenn ein Element gefressen wurde.
*/
function addPoints(pointsToAdd)
{
points += parseInt(pointsToAdd);
}

/**
* Prüft ob ein Snakepart auf der Schlange abgelegt wurde.
*
* @param droppedSnakePartX
* @param droppedSnakePartY
* @returns {boolean}
*/
function checkIfSnakePartIsDroppedOnSnake(droppedSnakePartX, droppedSnakePartY)
{
for (var i = 0; i < snake.length; i++) {
if(droppedSnakePartX == snake.x && droppedSnakePartY == snake.y) {
return true;
}
}

return false;
}

/**
*
* Generiert eine Zufallszahl
*
* @param min
* @param max
* @returns {number}
*/
function randomNumber(min, max)
{
return Math.round( Math.random() * (max - min) + min);
}



/**
* Startet das Spiel
*/
function init()
{
canvas = $("#canvas")[0];
context = canvas.getContext("2d");
snake = [];

snake.push(new SnakePart(0,0, 10, 10, "blue"));

draw_snake();

dropRandomSnakeparts();
}

init();

interval = window.setInterval(function(){
move_snake();
}, 100);
})
[/src]

Fertige Spiel wird dann veröffentlicht :)
 

Novgorod

ngb-Nutte

Registriert
14 Juli 2013
Beiträge
3.055
so, kleines update - die fancy version :D

labsnake.png


änderungen gegenüber 1.0:
- fancy grafik ("picture" statt 2D-farbbox-array), alle gezeichneten schlangenteile sind bitmaps
- bonuspunkte (grüner kreis mit "+" drin): ein bonuspunkt bringt 5 punkte, also 5 mal so viel wie ein normaler roter punkt, und verlängert die schlange nicht.. damit man aber nicht nur nach bonuspunkten jagt und die roten ignoriert, werden die bonusfelder zufällig generiert (4% wahrscheinlichkeit pro frame schien mir ein guter kompromiss) und verschwinden auch zufällig wieder - maximal ist nur ein bonuspunkt auf dem feld.. es lohnt sich also nur, einem bonuspunkt hinterherzulaufen, wenn man gerade "in der nähe" ist, sonst riskiert man unnötige umwege und damit kollisionen, besonders wenn die schlange schon länger geworden ist...
- der code ist ein kleines bisschen übersichtlicher (:rolleyes:) und besser kommentiert

labview ist nicht unbedingt am performantesten, wenn es um schnelles grafikzeugs geht, daher kann es sein, dass die performance etwas einbricht, wenn es sehr viel zu zeichnen gibt (d.h. wenn die schlange einen großteil des felds füllt).. bei moderaten frameraten sollte aber alles ok sein - ich habs bis 100fps getestet und <1% CPU last gehabt (aber bei 100fps kriegt man keine signifikante länge mehr hin :D)..

ich denke, damit sollte es erstmal gut sein, es sei denn jemand findet es extrem sinnvoll, die spielfeldgröße (und andere parameter) per ini festzulegen...

hier die .exe (die .vi ist mit im archiv):
Anhang anzeigen labsnake_1-1.zip

und hier die source-vorschau in flash:
Anhang anzeigen labsnake_1-1_source-preview.zip
 

Brother John

(schein)heilig

Registriert
1 Aug. 2013
Beiträge
235
@Brother John: Deine Hungrigen Würmer sehen ein bisschen nach "Nibbles" aus, du hast doch nicht etwa das Design ein bisschen abgekupfert :D
Ein bisschen? Von A bis Z, und ohne Scham! :D Nibbles hat damals den 80×25-Zeilen Textmodus verwendet und darauf mit Vorder-/Hintergrundtricks 50 Zeilen simuliert. Deswegen hat aber in manchen Situationen die Farbe der Snake nicht ganz gepasst. Hat mich genervt. Wollte ich weg haben. Schließlich hatte ich ne VGA-Karte, die echte 50 Zeilen konnte. Und dann ists halt ein bisschen mehr als nur ein Nibbles-Klon geworden.

@Novgorod
Danke für den Viewer! Auch wenn ich durch den »Quellcode« nicht wirklich durchblicke …
 

Thronplunder

nackt.

Registriert
14 Juli 2013
Beiträge
18.472
Ich versuche mich mal an Lisp :D Bin da allerdings nicht so der Held drin. Wird also nur moderat lispig.

Wie ich das mit der kompilierten exe mache, weiß ich noch nicht. Im Notfall stelle ich einfach ein Video bereit.
 
Oben