Joko luit kolme Applen Swift-ohjelmointikieltä käsittelevää opastani? Jos et, niin löydät niihin linkit tämän artikkelin lopusta. Tässä artikkelissa sovellamme opittuja tietoja ja rakennamme komentorivisovelluksen, joka arpoo lottonumerot. Sovellus arpoo luvut väliltä 1-39, estää samojen numeroiden esiintymisen ja asettaa rivin lopulta suurusjärjestykseen. Niinpä kyseessä ei ole aivan niin yksinkertainen sovellus, kuin voisi kuvitella. Sattumanvaraisten lukujen arpominen on helppoa, mutta koska huomioon täytyy ottaa päällekkäisyydet, joutuu koodaamisessa käyttämään hieman ajatusta. Lisäksi halusin vielä, että lottorivi on järjestyksessä pienimmästä suurimpaan, joka lisää oman osansa koodiin.
import Cocoa
var lotto = [0,0,0,0,0,0,0]
// Arvotaan seitsemän lukua yllä luotuun lotto-taulukkoon
for i in 0...6 {
lotto[i] = Int(arc4random_uniform(39) + 1)
}
Koko sovelluksen rakentaminen käynnistyy lotto-nimisen taulukon luonnista, johon arvotaan seitsemän sattumanvaraista lukua. Taulukon järjestysnumerot alkavat nollasta, eli ensimmäinen numero arvotaan kohtaan lotto[0] ja viimeinen lotto[6]. Lukujen arvonta suoritetaan arc4random_uniform-käskyllä, joka sopii tähän tarkoitukseen parhaiten. Siinä sulkeiden sisään merkitään suurin sallittu luku. Perässä oleva +1 varmistaa, että nolla ei ole arvottujen lukujen joukossa.
// Tarkastetaan lukujen päälekkäisyydet.
for k in 0...6 {
for b in 0...6 {
// Estetään lukujen vertailu samoista taulukon osista.
if k != b {
if lotto[b] == lotto[k] { // Jos luku on arvottu jo aiemmin, suoritetaan if-lause, joka varmistaa, että tilalle saadaan luku, jota ei ole tallennettu taulukkoon.
var y: Int
do {
y = Int(arc4random_uniform(39) + 1)
lotto[b] = y
} while lotto[b] == lotto[k] // Suoritetaan do-while-lause niin kauan, että tilalle saadaan varmasti toinen luku
}
}
}
}
Yllä lisäämme koodiin tärkeän osan, joka tarkistaa, että lottorivissä ei voi esiintyä samaa lukua kahta kertaa. Tässä hyödynnetään for-toistorakennetta, jonka avustamana lukuja verrataan toisiinsa. Jos koodimme havaitsee, että mukana on samoja lukuja, arpoo se uuden luvun ja asettaa sen taulukkoon. Tässä kohtaa käytän do-while-lausetta, joka on määritetty toistumaan niin monta kertaa, että tilalle on varmasti arvottu toinen luku. Periaatteessa ohjelma olis jo tällä hyvä, mutta hienosäätämällä saadaan lottorivi tulostumaan suuruusjärjestyksessä, joka helpottaa sen lukemista. Siitä lisää alla.
// Laitetaan numerot järjestykseen: pienimmästä suurimpaan
for j in 0...6 {
for n in 0...6 {
if lotto[j] < lotto[n] { // Asetetaan luvut uuteen järjestykseen
var pienempi = lotto[j]
var suurempi = lotto[n]
lotto[j] = suurempi
lotto[n] = pienempi
}
}
}
Kolmannessa koodiosassa jatkamme for-lauseen hyödyntämistä. Yllä oleva koodi käy jälleen numerot läpi ja asettaa ne taulukon sisällä uusille paikoille pienimmästä suurimpaan. Käytän if-lausetta, jolla vertaan lukujen suuruuksia ja sen mukaan järjestän ne uudelleen.
// Tulostetaan lotto-taulukon kaikki luvut.
println(lotto[0...6])
Viimeiseksi meillä jää enää lotto-taulukon tulostaminen, joka tapahtuu helpoten println-käskyllä. Näin meillä on simppeli komentoriviä hyödyntävä sovellus, joka arpoo seitsemän numeroa väliltä 1-39. Alla vielä koodi kokonaisuudessaan.
// Arpoo seitsemän numeroa väliltä 1-39
import Cocoa
var lotto = [0,0,0,0,0,0,0]
// Arvotaan seitsemän lukua yllä luotuun lotto-taulukkoon
for i in 0...6 {
lotto[i] = Int(arc4random_uniform(39) + 1)
}
// Tarkastetaan lukujen päälekkäisyydet.
for k in 0...6 {
for b in 0...6 {
// Estetään lukujen vertailu samoista taulukon osista.
if k != b {
if lotto[b] == lotto[k] { // Jos luku on arvottu jo aiemmin, suoritetaan if-lause, joka varmistaa, että tilalle saadaan luku, jota ei ole tallennettu taulukkoon.
var sama = b
var y: Int
do {
y = Int(arc4random_uniform(39) + 1)
lotto[b] = y
} while lotto[b] == lotto[k] // Suoritetaan di-while-lause niin kauan, että tilalle saadaan varmasti toinen luku
}
}
}
}
// Laitetaan numerot järjestykseen: pienimmästä suurimpaan
for j in 0...6 {
for n in 0...6 {
if lotto[j] < lotto[n] { // Asetetaan luvut uuteen järjestykseen
var pienempi = lotto[j]
var suurempi = lotto[n]
lotto[j] = suurempi
lotto[n] = pienempi
}
}
}
// Tulostetaan lotto-taulukon kaikki luvut.
println(lotto[0...6])
Mielenkiintoinen juttu. Ootan kyl et pääsee testaileen tätä Swiftia. Huomattavasti kyl helpostilähestyttävämpi kuin tuo Objective-C, ainakin näin pintapuolisesti.
En tiä onko kauheen validi kommentti, mutta tuli mieleen…
Nythän tuo arpoo numerot ja myöhemmin tarkistetaan esiintyykö samoja lukuja. Miltähän tuo näyttäisi jos numerot arvottaisiin niin, että kun numero valitaan se poistuisi myös ”valikoimasta”, jolloin samaa numeroa ei voisi esiintyä. Vaikuttaisi myös numeron satunnaisuuteen.
Loistava kommentti. Käytännössähän tuon ei pitäisi yllä olevan esimerkin perusteella olla vaikea toteuttaa mainitsemallasi tavalla. Ammattilainen kun en ole, niin en suoralta kädeltä osaa heittää tähän koodia. Toteuttaisin sen kuitenkin niin, että aina kun taulukkoon arvotaan uusi luku verrataan sitä muihin. Jos luku löytyy, arvotaan uudelleen.
Pitääpä testailla PlayGroundilla, jos löytyy aikaa. :-))
Ehkä oon vähän pinttyny tohon mun ajatukseen, mutta vielä vähän tarkentaisin…
Eli vertaisin hieman tuohon oikeaan prosessiin… kun pallo valitaan, sehän lähtee mahdollisista valinnoista pois. Jäljelle jäävistä palloista valitaan seuraavat numerot. En oikeastaan tiedä onko tuolla hirveästi väliä, mutta lähinnä tuo ajatuksena on hieman eri kuin se jos testataan onko numero jo valittu.
Eli tavallaa kyseinen luku ei olisi enää arvottavien lukujen joukossa? Nyt ymmärsin, mitä ajoit takaa. 🙂
Jep, juurikin näin. 😀
Kokeilin yksinkertaistaa koodia ja päädyin seuraavaan muotoon.
import Cocoa
// Kaikki mahdolliset numerot
var all = [Int]()
for i in 0...38 {
all.append(i + 1)
}
// all=[1,2,3,...,39]
// http://en.wikipedia.org/wiki/Fisher–Yates_shuffle
for i in 0...6 {
// satunnainen indeksi 0...38
var j = Int(arc4random_uniform(39))
// vaihdetaan all[i] ja all[j] arvot keskenään
var cur_all_i = all[i]
var cur_all_j = all[j]
all[i] = cur_all_j
all[j] = cur_all_i
}
// lottorivi on ensimmäiset 7 numeroa
var lotto = all[0...6]
// järjestetään pienimmästä suurimpaan
lotto.sort { $0 < $1 }
// lottorivi
println(lotto)
No niin, nyt on ammattilainen asialla. 🙂 Todella kompaktiin pakettiin olet koodin saanut.