[#1] Wyzwania programistyczne
Widziałem coś takiego na jakimś forum. Język programowania dowolny. Dobrze by było gdyby autor opublikował kod, efekty działania programu itp.

Wyzwanie nr 1:



Oczywiście jeżeli ktoś posiada jakieś pomysły do realizacji to miło by było je tutaj umieścić jako nowe wyzwanie. Pamiętajmy, że to tylko zabawa dla rozrywki i relaksu przy Amidze.
[#2] Re: Wyzwania programistyczne

@chicago, post #1

Oczywiście AMOS, oczywiście cały kod...

Screen Open 0,320,256,4,Lowres : Curs Off : Flash Off : Hide On : Cls 0
Degree 
Palette $0,$888,$FFF
Dim X(3),Y(3)
ALFA=Rnd(119)
For A=0 To 2
   X(A)=160+100*Sin(ALFA+120*A)
   Y(A)=128+100*Cos(ALFA+120*A)
Next A
Ink 1
Draw X(0),Y(0) To X(1),Y(1)
Draw X(1),Y(1) To X(2),Y(2)
Draw X(2),Y(2) To X(0),Y(0)
Ink 2
For A=0 To 2
   Plot X(A),Y(A)
Next A
X0=Rnd(319)
Y0=Rnd(255)
For A=0 To 100 : Rem tutaj ustalamy ilość kroków
   ZMIENNA=Rnd(2)
   If X0>X(ZMIENNA)
      X1=X0-((X0-X(ZMIENNA))/2)
   Else 
      X1=X0+((X(ZMIENNA)-X0)/2)
   End If 
   If Y0>Y(ZMIENNA)
      Y1=Y0-((Y0-Y(ZMIENNA))/2)
   Else 
      Y1=Y0+((Y(ZMIENNA)-Y0)/2)
   End If 
   Ink 1
   Draw X0,Y0 To X1,Y1
   Ink 2
   Plot X0,Y0
   Wait Vbl 
   X0=X1
   Y0=Y1
Next A


Acha, dodatkowo początkowy trójkąt jest rysowany w losowej pozycji, ilość kroków wyrysowywania zmieniamy w ostatniej pętli for, oznaczone komentarzem

Ostatnia aktualizacja: 24.09.2018 17:19:31 przez Mandi
[#3] Re: Wyzwania programistyczne

@Mandi, post #2

Trochę dziwnie masz wyznaczanie nowego punktu. Nie wystarczy x1 = (x0 + x(zmienna))/2? (+ to samo dla y). No i bez przesady. Wyzwanie?
[#4] Re: Wyzwania programistyczne

@Mandi, post #2

Wersja nieco zoptymizowana...
Screen Open 0,320,256,4,Lowres : Curs Off : Flash Off : Hide On : Cls 0
Degree 
Palette $0,$888,$FFF
Dim X(3),Y(3)
ALFA=Rnd(119)
For A=0 To 2
   X(A)=160+100*Sin(ALFA+120*A)
   Y(A)=128+100*Cos(ALFA+120*A)
Next A
Ink 1
Draw X(0),Y(0) To X(1),Y(1)
Draw X(1),Y(1) To X(2),Y(2)
Draw X(2),Y(2) To X(0),Y(0)
Ink 2
For A=0 To 2
   Plot X(A),Y(A)
Next A
X0=Rnd(319)
Y0=Rnd(255)
For A=0 To 100  : Rem tutaj ustalamy ilość kroków
   ZMIENNA=Rnd(2)
   X1=X0-((X0-X(ZMIENNA))/2)
   Y1=Y0-((Y0-Y(ZMIENNA))/2)
   Ink 1
   Draw X0,Y0 To X1,Y1
   Ink 2
   Plot X0,Y0
   Wait Vbl 
   X0=X1
   Y0=Y1
Next A
[#5] Re: Wyzwania programistyczne

@kiero, post #3

Kiero też się na to złapałem... że zrobiłem nieoptymalnie, stąd kiedy pisałeś komenta ja robiłem poprawkę

A co do tego co napisałeś, nie wystarczy, bo to nie miało się przesunąć o połowę współrzędnych danego wierzchołka, ale o połowę różnicy między punktami


Ostatnia aktualizacja: 24.09.2018 18:16:45 przez Mandi

Ostatnia aktualizacja: 24.09.2018 18:18:11 przez Mandi
[wyróżniony] [#6] Re: Wyzwania programistyczne

@kiero, post #3

Myślę że poziom celowo jest dobrany tak by zachęcać, a nie zniechęcać. ;)

No, wersję amosową mamy. Ktoś w innym języku zrobi to samo?
[#7] Re: Wyzwania programistyczne

@Mandi, post #5

Mandi:

X1=X0-((X0-X(ZMIENNA))/2)

x1 = x0 - (x0/2 - x(zmienna)/2)
x1 = x0 - x0/2 + x(zmienna)/2
x1 = x0/2 + x(zmienna)/2
x1 = (x0 + x(zmienna)) / 2

;)
[#8] Re: Wyzwania programistyczne

@kiero, post #7

OK, Twpja Babcia starsza Dajmy się wykazać miszczom BBasic, AmigaE, C, Asm i wszelakich innych
[#9] Re: Wyzwania programistyczne

@Mandi, post #2

A możesz wrzucić jak to się wykona? Oczywiście wynikiem programu będzie.....?
[#10] Re: Wyzwania programistyczne

@chicago, post #9

[blah, bessensu]

Ostatnia aktualizacja: 24.09.2018 21:11:54 przez kiero
[#11] Re: Wyzwania programistyczne

@kiero, post #10

Nie bez sensu. Wynikiem jest trojkat sierpienskiego. Sztuczka polega tylko na tym zeby nie rysowac linii miedzy punktami.
[#12] Re: Wyzwania programistyczne

@chicago, post #1

Marna wersja w pythonie (wymaga pygame):

import pygame
import math
import random

# Rozmiar planszy
(width, height) = (800, 800)

# Wysokosc trojkata
triangle_h = 600
triangle_a = int(triangle_h * 2 / math.sqrt(3))

# Koordynaty trojkata - zawsze na srodku okna
triangle = ((width/2, height/2-triangle_h/2), 
            (width/2 - triangle_a / 2, height / 2+triangle_h/2), 
            (width/2 + triangle_a / 2, height/2+triangle_h/2))

# Przygotowanie planszy
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Trojkat sierpienskiego')
screen.fill((255, 255, 255))
pygame.draw.line(screen, (50, 50, 50), triangle[0], triangle[1], 2)
pygame.draw.line(screen, (50, 50, 50), triangle[0], triangle[2], 2)
pygame.draw.line(screen, (50, 50, 50), triangle[1], triangle[2], 2)
pygame.display.flip()

# Wylosuj pierwszy punkt
x = (random.randint(0, width-1), random.randint(0, height-1))

cnt = 0
running = True

# Glowna petla
while running:
  cnt = cnt + 1
  
  # Rysuj punkt
  pygame.draw.line(screen, (100, 0, 0), x, x, 1)
  
  # Wylosuj jeden z punktow trojkata
  tx = triangle[random.randint(0, 2)]

  # Oblicz nowe koordynaty
  x = ((x[0] + tx[0]) / 2, (x[1] + tx[1]) / 2)

  # Co 100 iteracji odswierz plansze
  if cnt % 100 == 0:
    pygame.display.flip()

  # Obsluga wyjscia z programu
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
[#13] Re: Wyzwania programistyczne

@chicago, post #9

A proszę... Chociaż szybciej było to do AMOSa skopiować

[#14] Re: Wyzwania programistyczne

@mschulz, post #12

jeszcze obrazek


Ostatnia aktualizacja: 24.09.2018 21:41:00 przez mschulz
[#15] Re: Wyzwania programistyczne

@mschulz, post #11

Hehe, nie nie, nie o takie bez sensu mi chodzilo:) Po prostu skasowałem co napisałem.
[#16] Re: Wyzwania programistyczne

@chicago, post #1

Wersja bez rysowania linii (obrazek mnie zmylił )

Screen Open 0,320,256,4,Lowres : Curs Off : Flash Off : Hide On : Cls 0
Degree 
Palette $0,$888,$FFF
Dim X(3),Y(3)
ALFA=Rnd(119)
For A=0 To 2
   X(A)=160+100*Sin(ALFA+120*A)
   Y(A)=128+100*Cos(ALFA+120*A)
Next A
Ink 1
Draw X(0),Y(0) To X(1),Y(1)
Draw X(1),Y(1) To X(2),Y(2)
Draw X(2),Y(2) To X(0),Y(0)
Ink 2
For A=0 To 2
   Plot X(A),Y(A)
Next A
X0=Rnd(319)
Y0=Rnd(255)
For A=0 To 5000
   ZMIENNA=Rnd(2)
   X1=X0-((X0-X(ZMIENNA))/2)
   Y1=Y0-((Y0-Y(ZMIENNA))/2)
   Ink 2
   Plot X0,Y0
   X0=X1
   Y0=Y1
Next A


[#17] Re: Wyzwania programistyczne

@Mandi, post #16

Ladniejsza wersja bedzie jeszcze jezeli kolory punktow ustawi sie w zaleznosci od odleglosci rysowanego punktu od wierzcholkow trojkata:

# Wylosuj jeden z punktow trojkata
  tx = triangle[random.randint(0, 2)]

  # Oblicz nowe koordynaty
  x = ((x[0] + tx[0]) / 2, (x[1] + tx[1]) / 2)

  # Oblicz odleglosci od wierzcholkow
  d1 = math.sqrt((x[0] - triangle[0][0])*(x[0] - triangle[0][0]) + (x[1] - triangle[0][1])*(x[1] - triangle[0][1]))
  d2 = math.sqrt((x[0] - triangle[1][0])*(x[0] - triangle[1][0]) + (x[1] - triangle[1][1])*(x[1] - triangle[1][1]))
  d3 = math.sqrt((x[0] - triangle[2][0])*(x[0] - triangle[2][0]) + (x[1] - triangle[2][1])*(x[1] - triangle[2][1]))

  # Oblicz kolor
  kolor = (200 * (1 - d1 / triangle_a), 200 * (1 - d2 / triangle_a), 200 * (1 - d3 / triangle_a))
  
  # Rysuj punkt
  pygame.draw.line(screen, kolor, x, x, 1)


wtedy taki potworek wychodzi:

[#18] Re: Wyzwania programistyczne

@chicago, post #1

Czemu nie szeroki uśmiech
Prosze bardzo, wersja w BB2 (nawet dziala)
Po skompilowaniu zajmuje 23396 - troche duzo ale chyba dlatego ze dodalem ustawianie okna na podstawie ekranu WB

#IDCMP_RAWKEY      = $0400
#WFLG_ACTIVATE     = $1000
#WFLG_BORDERLESS   = $0800

finito.b           = False

NEWTYPE.xy
 x.w
 y.w
End NEWTYPE
Dim tri.xy(3)

DEFTYPE.Screen *wb
DEFTYPE.w
;---------------------------------------------------



; ustawiam ekran WB jako widoczny
WbToScreen 0
ShowScreen 0

; ten program mozna wystartowac z ikonki
WBStartup

; okno CLI zostanie schowane
NoCli


; pobieram informacje o ekranie by moc dostosowac rozmiar okna
*wb = LockPubScreen_(0)
If *wb
  ww=*wb\Width
  wh=*wb\Height-*wb\BarHeight-1
  wy=*wb\BarHeight+1
  UnlockPubScreen_ 0,*wb
Else
  End
EndIf


; wyliczam trojkat
th       = wh-4
ta       = 2*th/Sqr(3)

tri(0)\x = ww/2,         (wh-th)/2
tri(1)\x = (ww-ta)/2+ta, (wh-th)/2+th
tri(2)\x = (ww-ta)/2,    (wh-th)/2+th


; otwieram okno
Window 1,0,wy,ww,wh,#WFLG_BORDERLESS|#WFLG_ACTIVATE,"",1,2


; losuje punkt srtartowy w oknie
rp.xy\x = Rnd(ww-1),Rnd(wh-1)


; glowna petla programu
; ESC konczy dzialanie calosci
Repeat
  ; jesli ESC zostal presniety to finito
  If Event=#IDCMP_RAWKEY
    rk$=Inkey$
    If RawKey = $45 Then finito = True
  EndIf

  ; losuje wierzcholek
  p.b = Rnd(3)

  ; obliczam kolejny punkt startowy na podstawie wylosowanego wierzcholka
  rp\x = tri(p)\x + (rp\x-tri(p)\x)/2, tri(p)\y + (rp\y-tri(p)\y)/2

 ; rysuje punkt
  WPlot rp\x,rp\y,1
Until finito

End


no i wynik:


przyznam sie ze chcialbym zobaczyc to w asemblerze :)
[#19] Re: Wyzwania programistyczne

@peceha, post #18

przyznam sie ze chcialbym zobaczyc to w asemblerze
W asemblerze o tyle mi się nie chce, że trzeba napisać jakiś generator liczb pseudolosowych...
[#20] Re: Wyzwania programistyczne

@Krashan, post #19

Akurat niedawno na EAB byl temat Random number generator i oto kod z niego:
move.w $dff006,d0
 swap d0
 move.b $bfe801,d0
 lsl.w #8,d0
 move.b $bfd800,d0


Nie mam pojecia na co patrze szeroki uśmiech ale chyba to byloby to hehe
[#21] Re: Wyzwania programistyczne

@Krashan, post #19

W asemblerze o tyle mi się nie chce, że trzeba napisać jakiś generator liczb pseudolosowych...


Prosze bardzo:

rand:
        move.l _seed,d0
        muls.l #1103515245,d0
        add.l #12345,d0
        bclr #31,d0
        move.l d0,_seed
        and.l #255,d0
        rts


Ostatnia aktualizacja: 25.09.2018 10:50:56 przez mschulz
[#22] Re: Wyzwania programistyczne

@peceha, post #18

Mozesz jeszcze uproscic liczenie nowego punktu, nie wiem czy blitz to zoptymalizuje czy nie:

rp\x = (rp\x+tri(p)\x)/2, (rp\y+tri(p)\y)/2


zgodnie z zasada ze srodek odcinka to srednia arytmetyczna wierzcholkow :)
[#23] Re: Wyzwania programistyczne

@mschulz, post #21

Heh, to ja dorzuce cos prostszego. Chyba blueberry kiedys na ada wrzucil:

(d0 - seed)

ror.l d0, d0
sub.l #1, d0

:)
[#24] Re: Wyzwania programistyczne

@mschulz, post #22

Mozesz jeszcze uproscic liczenie nowego punktu


No faktycznie
[#25] Re: Wyzwania programistyczne

@mschulz, post #12

Myślałem że to wyzwania programistyczne na amidze ?
[#26] Re: Wyzwania programistyczne

@Goor, post #25

Myślałem że to wyzwania programistyczne na amidze ?


A nie bylo pythona na os4/morphos-a?
[#27] Re: Wyzwania programistyczne

@mschulz, post #26

A nie bylo pythona na os4/morphos-a?
Robiłeś to pod OS4, czy MorphOS-em?
[#28] Re: Wyzwania programistyczne

@Krashan, post #27

Robiłeś to pod OS4, czy MorphOS-em?


Ok, nie bede juz cisnal :P W ramach pokuty popelnilem wersje w C pod AmigaOS. Pisana co prawda na maku i kompilowana skrosnie ale uruchomiona pod FSUAE.

Czy mam wybaczone? Brawo! Zmusiles mnie do napisania programu pod Amige. Pierwszego od lat :)

PS. Binarka (niewiele ponad 1KB, wymaga 68020 z powodu 32-bitowego muls) jest tutaj: link

PPS. Obrazek z dzialania programu:


Wybaczcie brzydki kod ;)
#include <exec/types.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <workbench/startup.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <utility/tagitem.h>

#undef SysBase
struct ExecBase *SysBase;

int main();

/* Minimalny kod startowy */
void _start()
{
    struct Process *p = NULL;
    struct WBStartup *wbmsg = NULL;

    SysBase = *(struct ExecBase **)4UL;
    p = (struct Process *)SysBase->ThisTask;

    if (p->pr_CLI == 0)
    {
        WaitPort(&p->pr_MsgPort);
        wbmsg = (struct WBStartup *)GetMsg(&p->pr_MsgPort);
    }

    main();

    if (wbmsg)
    {
        Forbid();
        ReplyMsg((struct Message *)wbmsg);
    }
}

static const char __attribute__((used)) verstring[] = "\0$VER: Dywan 0.1 (25.09.2018)\n\0";

#define WINDOW_WIDTH    400
#define WINDOW_HEIGHT   400
#define TRIANGLE_H      (WINDOW_HEIGHT * 4 / 5)
#define TRIANGLE_A      (TRIANGLE_H * 2 * 1000 / 1732)

ULONG seed = 0xdeadbeef;

ULONG rand()
{
    seed = ((seed * 1103515245) + 12345) & 0x7fffffff;
    return seed;
}

struct Point {
    UWORD x;
    UWORD y;
};

struct Point points[3] = {
    { WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 - TRIANGLE_H / 2 },
    { WINDOW_WIDTH / 2 - TRIANGLE_A / 2, WINDOW_HEIGHT / 2 + TRIANGLE_H / 2 },
    { WINDOW_WIDTH / 2 + TRIANGLE_A / 2, WINDOW_HEIGHT / 2 + TRIANGLE_H / 2 }
};

int main()
{
    struct IntuitionBase * IntuitionBase = NULL;
    struct GfxBase * GfxBase = NULL;

    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
    
    if (IntuitionBase != NULL)
    {
        GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);

        if (GfxBase != NULL)
        {
            struct Window *myWindow = OpenWindowTags(0, WA_InnerWidth, WINDOW_WIDTH,
                                         WA_InnerHeight, WINDOW_HEIGHT,
                                         WA_DepthGadget, TRUE,
                                         WA_CloseGadget, TRUE,
                                         WA_DragBar, TRUE,
                                         WA_Title, (Tag)"Dywan",
                                         WA_Activate, TRUE,
                                         WA_GimmeZeroZero, TRUE,
                                         WA_IDCMP, IDCMP_MOUSEBUTTONS|IDCMP_CLOSEWINDOW,
                                         TAG_DONE);
            
            if (myWindow != NULL)
            {
                struct RastPort *rastPort = myWindow->RPort;
                BYTE running = TRUE;
                SetAPen(rastPort, 1);

                /* Wylosuj pierwszy punkt */
                UWORD x = rand() % WINDOW_WIDTH;
                UWORD y = rand() % WINDOW_HEIGHT;

                Move(rastPort, points[0].x, points[0].y);
                Draw(rastPort, points[1].x, points[1].y);
                Draw(rastPort, points[2].x, points[2].y);
                Draw(rastPort, points[0].x, points[0].y);

                do {
                    struct IntuiMessage *msg;
                    UWORD class;

                    while ((msg = (struct IntuiMessage *)GetMsg(myWindow->UserPort)) != 0)
                    {
                        class = msg->Class;

                        ReplyMsg((struct Message *)msg);

                        if (class == IDCMP_CLOSEWINDOW)
                        {
                            running = FALSE;
                        }
                    }

                    /* Wylosuj punkt trojkata */
                    UWORD p = rand() % 3;

                    x = (x + points[p].x) / 2;
                    y = (y + points[p].y) / 2;

                    WritePixel(rastPort, x, y);

                } while(running == TRUE);

                CloseWindow(myWindow);
            }

            CloseLibrary((struct Library *)GfxBase);
        }

        CloseLibrary((struct Library *)IntuitionBase);
    }

    return 0;
}


Ostatnia aktualizacja: 25.09.2018 15:46:35 przez mschulz
[#29] Re: Wyzwania programistyczne

@mschulz, post #28

Instrukcja kompilacji:
Wymaga gcc-6 od bebbo (https://github.com/bebbo/amiga-gcc):
m68k-amigaos-gcc -noixemul -Os -m68020 -nostartfiles -o dywan main.c
[#30] Re: Wyzwania programistyczne

@mschulz, post #28

~1 KB?
Z ciekawości zobaczę co da się zrobić z wersją z blitz-a.
Bo toż to olbrzym jakiś wyszedł u mnie.

@Mandi
A plik wykonywalny z amosa ile zajmuje?
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem