Ennakkoa ottava ampuja

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Ennakkoa ottava ampuja

Post by Aavesoturi »

Tuunasin huvikseni Tappelu minipeliini tekoälyn joka osaa laskea ammuksilleen ennakon eli jos liiku koko ajan samaan suuntaan sen pitäisi osua aina. Koodia on kommentoitu jonkun verran, ennakon laskenta tapahtuu AI-subissa. Perusasetuksilla on erittäin vaikea saada enemmän osumia kuin tekoäly, joten alussa olevia vakioita säätämällä voi tehtävää helpottaa. AI pelaaja ei liiku.

Code: Select all

// Tappelu AI Edition
// Ennakon laskeminen ammukselle
// Tehny Aavesoturi
// Saapi käyttää vapaasti

SCREEN 800,600,0,cbWindowed

// vakiot, joilla voi säätää kaikenlaista
Const maxShots    = 20      // maksimi määrä ammuksia kerralla pelissä
Const turnRate    = 5.0     // kuinka nopeasti pelaajat kääntyy (astetta / frame)
Const speed       = 2.0     // pelaajien liikkumisnopeus (pikseliä / frame)
Const shotRange   = 900.0   // ammusten kantama (pikseliä)
Const shotSpeed   = 5.0     // ammusten nopeus (pikseliä / frame)
Const loadingTime = 500     // latausaika (millisekuntia)
Const radius      = 8       // pelaajan "hahmon" säde (pikseliä)
// end of vakiot

Dim x1#, y1#, x2#, y2#, a1#, a2#, t1, t2
Dim ai_recX#, ai_recY#, a#, theta#, phi#, dir#
Dim points1, points2
Dim shots(maxShots, 3) As Float

// aloituspaikat
x1 = ScreenWidth()/4*3
y1 = ScreenHeight()/2
a1 = 0
x2 = ScreenWidth()/4
y2 = ScreenHeight()/2
a2 = 180

Dim i
// PÄÄLUUPPI
Repeat
    Gosub Keys
    Gosub AI
    Gosub Shots
    Gosub Display
Forever
// END OF PÄÄLUUPPI

// Ihmispelaajan nappulat
Keys:
    a1 = a1 - ( RightKey()-LeftKey() ) * turnRate
    s = UpKey() * speed
    x1 = x1 + Cos(a1) * s
    y1 = y1 - Sin(a1) * s
    If KeyDown(cbKeySpace) And Timer() > t1 + loadingTime Then Fire(x1,y1,a1): t1 = Timer()
Return

// Laskee vakio nopeudella liikkuvalle kohteelle ennakon eli mihin tulisi ampua jotta osuu
// ja kääntää vihupelaajaa sen mukaisesti sekä ampuu jos saa piikille
AI:
    a#     = GetAngle(x2,y2,x1,y1)                          'kulma kohteeseen
    theta# = Distance(x1,y1,ai_recX,ai_recY) / shotSpeed    'kohteen ja ammuksen nopeuksien suhde
    phi#   = theta * Sin( a1 - a )
    If Abs(phi) < 1 Then        'phi:n täytyy olla välillä ]-1,1[ jotta arcsin antaisi järkevää tulosta
        dir# = a + ASin(phi)    'kulma johon pyritään kääntymään
        If Abs(dir-a2) <= turnRate Then 'jos ollaan lähellä, käännytään suoraan
            a2 = dir                    'tämän voisi laskea huijaamiseksi, koska käännytään tarkemmin kun ihmisen on mahdollista
        Else                            'jos ollaan kauempana ni käännytään lähemmän suunnan kautta turnRaten verran
            a2 = NearestAngle(dir, a2 + turnRate, a2 - turnRate)
        EndIf
    EndIf
    // Jos ollaan tarpeeksi lähellä laskettua kulmaa, ammutaan (2:n asteen tarkkuus on tässä riittävä)
    If Abs(dir-a2) < 2 And Timer() > t2 + loadingTime Then Fire(x2,y2,a2): t2 = Timer()
    // Otetaan pelaajan koordinaatit muistiin, jotta voidaan laskea pelaajan nopeus
    ai_recX = x1
    ai_recY = y1
Return

// Liikuttaa, laskee törmäykset, poistaa ja piirtää ammukset
Shots:
    For i = 0 To maxShots
        If shots(i,0) > 0 Then
            shots(i,0) = shots(i,0) - shotSpeed
            shots(i,1) = shots(i,1) + Cos(shots(i,3)) * shotSpeed
            shots(i,2) = shots(i,2) - Sin(shots(i,3)) * shotSpeed
            If Distance(shots(i,1), shots(i,2), x1, y1) < radius * 2 Then shots(i,0) = 0: points2+1
            If Distance(shots(i,1), shots(i,2), x2, y2) < radius * 2 Then shots(i,0) = 0: points1+1
            Color cbWhite: Dot shots(i,1), shots(i,2)
        EndIf
    Next i
Return

// Piirtää pelaajat ja pisteet
Display:
        Color 255,80,255 : Circle x1-radius,y1-radius,radius*2,OFF
        Color cbWhite    : Line x1,y1,x1+Cos(a1)*(radius*2),y1-Sin(a1)*(radius*2)
        Color 80,248,255 : Circle x2-radius,y2-radius,radius*2,OFF
        Color cbWhite    : Line x2,y2,x2+Cos(a2)*(radius*2),y2-Sin(a2)*(radius*2)
        Color 80,248,255 : Text 10, 10, "Cyan score: "+points2
        Color 255,80,255 : Text ScreenWidth() - TextWidth("Magenta score: "+points2)-10, 10, "Magenta score: "+points1
        DrawScreen
Return

// Luo uuden ammuksen ja ampuu sen
Function Fire(x#, y#, a#)
    Dim i
    For i = 0 To maxShots
        If shots(i,0) <= 0 Then
            shots(i,0) = shotRange
            shots(i,1) = x + (radius*2) * Cos(a)
            shots(i,2) = y - (radius*2) * Sin(a)
            shots(i,3) = a
            Exit
        EndIf
    Next i
End Function

// Palauttaa kulman (ang1 tai ang2), joka on lähimpänä kulmaa ang
Function NearestAngle#(ang#,ang1#,ang2#) 'by Astigma
   ang1 = WrapAngle(ang1)
   ang2 = WrapAngle(ang2)
   If Distance(Cos(ang),Sin(ang),Cos(ang1),Sin(ang1)) < Distance(Cos(ang),Sin(ang),Cos(ang2),Sin(ang2)) Then Return ang1 Else Return ang2
End Function
regalis
Advanced Member
Posts: 268
Joined: Mon Aug 27, 2007 9:44 pm

Re: Ennakkoa ottava ampuja

Post by regalis »

Tämähän on kätevä systeemi. :) Useimmissa CB-tekoälyissä ongelmana on juuri se, että botit eivät meinaa osua liikkuviin kohteisiin (tosin pystyy tätäkin melko helposti huijaamaan liikkumalla "siksakkia"). Mutta joka tapauksessa todella hyödyllinen bottien tekoälyä tehdessä.
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Ennakkoa ottava ampuja

Post by koodaaja »

Hiiritähtäyksellä tämäkin olisi helposti rökitettävissä siksakilla, mutta pelkästään näppiksellä pelattaessa se on varsin voittamaton. Jos tällaisia tekoälyjä saadaan useisiin CB-peleihin, voi niistä tulla jopa haastavia :o (olettaen toki, että liikkuvat : D se onkin sitten seuraava tekemisen kohde, vai?) Mutta varsin hieno tekoäly tosiaan.
otto90x
Advanced Member
Posts: 349
Joined: Mon Aug 27, 2007 9:00 pm
Location: Lapinjärvi, Finland
Contact:

Re: Ennakkoa ottava ampuja

Post by otto90x »

Näköjään tämän saa ampumaan huteja myös liikkumalla vain pieninä nykäyksinä, mutta varsin hyvä tekoäly kuitenkin.
Otto Martikainen a.k.a. MetalRain, otto90x, kAATOSade.
Runoblogi, vuodatusta ja sekoiluja.
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Ennakkoa ottava ampuja

Post by Aavesoturi »

(olettaen toki, että liikkuvat : D se onkin sitten seuraava tekemisen kohde, vai?)
Tekoäly on tietty mielenkiintoinen aihealue, mutta tämän kursin kokoon lähinnä hetken mielijohteesta, kun en muista ennen nähneeni ennakkoa ottavia botteja täällä ja tuo on kuitenkin niin yksinkertainen (eihän siihen laskentaan käytetä kun muutama rivi) kikka jolla saa huomattavasti tehokkaampia vihollisia, että kannattaa käyttää.
Näköjään tämän saa ampumaan huteja myös liikkumalla vain pieninä nykäyksinä, mutta varsin hyvä tekoäly kuitenkin.
Joo siis eihän tuo muuta tee kun laskee että mihin ampumalla osuu jos kohde jatkaa liikettään samanlaisena jonkun aikaa.

On mahdotonta tehdä tekoälyä, joka osuisi aina; tietty erittäin suurella vaivalla voisi rakentaa systeemin, jossa kohteen liikettä analysoidaan hieman pidemmän aikavälin aikana, josta sitten luotaisiin malli sen liikeradalle, ja siten saatettaisiin osua myös siksakkaaviin ja kiihtyvässä liikkeessä oleviin kohteisiin, mutta jälleen yllättävä poikkeama siitä mallista luodin lennon aikana aiheuttaa hudin.

Itseasiassa huomasin juuri ennen koodin postaamista, että tuota on helppo jallittaa kulkemalla takaperin, koska se ei huomio kohteen liikesuuntaa vaan sen katsomissuunnan, joten luonnollisena ratkaisuna poistin peruutus ominaisuuden :) Korjaan jahka jaksan/kerkiän. ;)
atomimalli
Moderator
Moderator
Posts: 227
Joined: Wed Aug 29, 2007 3:55 pm

Re: Ennakkoa ottava ampuja

Post by atomimalli »

Fourierin muunnos voisi olla yksinkertaisin ratkaisu monimutkaisemman väistelyn ennakoimiseen, mikään siksakki ei enään siinä vaiheessa auta paria sekuntia pidempään. Kiihtyvänkin liikkeen ennakoiminen voisi olla mahdollista jne.
Taitaa kyllä mennä sellasen monimutkaisuuden puolelle kaikesta huolimatta että sellasen kehittämisestä käy kyllä kunnon työstä.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Ennakkoa ottava ampuja

Post by Koodiapina »

Näyttää sen verran mainiolta, että tulen käyttämään sitä aina jos tarvitsen bottia ampumaan pelaajaa. Tekoälyssä on pieniä vikoja, mutta ne antavat pelaajalle vain mahdollisuuksia.
mokkeri
Member
Posts: 84
Joined: Sat Apr 05, 2008 9:22 pm

Re: Ennakkoa ottava ampuja

Post by mokkeri »

koodaaja wrote:Hiiritähtäyksellä tämäkin olisi helposti rökitettävissä siksakilla, mutta pelkästään näppiksellä pelattaessa se on varsin voittamaton.
Totta, mutta hyvä on
asd
MAVmaggot
Advanced Member
Posts: 468
Joined: Fri Aug 31, 2007 10:18 pm
Location: bitspace

Re: Ennakkoa ottava ampuja

Post by MAVmaggot »

tosi hyvä, kiitos :D ärsyttävän mahdaoton voittaa ;) Mutta niinkuin koodaja sanoi, hiirellä ja siksakilla on helppo voittaa. Eli voisi lisätä semmosen, että kun menee itse siksakkia, niin botti ennakoisi senkin :D ;)
Olwi
Devoted Member
Posts: 557
Joined: Sun Dec 30, 2007 4:15 pm
Location: Muhos

Re: Ennakkoa ottava ampuja

Post by Olwi »

Tadaa:
Cyan score:7 Magenta score:8

Kauan sain yrittää:D
Huuda mun ip:tä!
nevssons
Devoted Member
Posts: 503
Joined: Sun Jan 13, 2008 5:02 pm

Re: Ennakkoa ottava ampuja

Post by nevssons »

0-53 :D (muutin vähän asetuksia ja laitoin taakse liikkumisen)
Koodarina kohtalainen, henkilönä vittumainen
Image
Olwi
Devoted Member
Posts: 557
Joined: Sun Dec 30, 2007 4:15 pm
Location: Muhos

Re: Ennakkoa ottava ampuja

Post by Olwi »

nevssons wrote:0-53 :D (muutin vähän asetuksia ja laitoin taakse liikkumisen)
No onhan se tuollai helppo ku se ampuu jatkuvasti ohi:)
Huuda mun ip:tä!
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Ennakkoa ottava ampuja

Post by koodaaja »

"Muutin vähän asetuksia", kuulostaa huijaamiselta ;D Jos esimerkiksi pistää luotien nopeuden hyvin hitaaksi, ehdit väistellä ne, kun taas vastustaja pysyy paikallaan. Ja se menee pahasti sekaisin pakittelusta, mikä todettiinkin jo :p
nevssons
Devoted Member
Posts: 503
Joined: Sun Jan 13, 2008 5:02 pm

Re: Ennakkoa ottava ampuja

Post by nevssons »

koodaaja wrote:"Muutin vähän asetuksia", kuulostaa huijaamiselta ;D Jos esimerkiksi pistää luotien nopeuden hyvin hitaaksi, ehdit väistellä ne, kun taas vastustaja pysyy paikallaan. Ja se menee pahasti sekaisin pakittelusta, mikä todettiinkin jo :p
Itse asiassa laitoin vaan taakse liikkumisen
Koodarina kohtalainen, henkilönä vittumainen
Image
phons
Guru
Posts: 1056
Joined: Wed May 14, 2008 10:11 am

Re: Ennakkoa ottava ampuja

Post by phons »

Vau, tämä olikin hieno ton pallon ohjaaminen tosin oli vähän vaikeeta.

Noi vielä vaihtaa objekteiksi ja tekee sinne jotain maailmaa niin siinähän on ihan hyvä peli jo kasassa vielä kun vähän värkkää. :D :D
Image
Post Reply