Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Apua Java ohjelmointitehtävään

Sivun loppuun

LateKuusila [26.11.2021 14:37:42]

#

Hei,

Kaipaisin apua ja vinkkejä, että miten seuraavanlainen tehtävä kannattaisi tehdä:

Tee viisinumeroisen numerokoodin arvauspeli. Pelaajan tehtävänä on arvata ohjelman arpoma
viisinumeroinen koodi. Ohjelma kysyy pelaajalta hänen arvaamaansa koodia yksi numero kerrallaan.
Koodin selvittämisen tueksi ohjelma palauttaa jokaisen arvauksen jälkeen vihjeeksi kaksi numeroa.
Vihjeen ensimmäinen numero kertoo, montako numeroa on oikealla paikalla ja toinen oikein
arvattujen numeroiden summan. Ohjelma pitää kirjaa siitä, montako arvauskertaa pelaaja tarvitsee
koodin selvittämiseen.
Vihje: Sijoita kumpikin omaan viisisoluiseen taulukkoon.
Esimerkiksi: Arvattava koodi on 53840 ja käyttäjän arvaamat numerot ovat 83241. Tällöin numerot
3 ja 4 ovat oikealla paikalla ja ohjelma täten tulostaa vihjeeksi numerot 2 ja 7.
Toteuta ohjelma metodeja hyödyntäen. Ohjelma sisältää ainakin seuraavat metodit:
- Metodi, joka arpoo arvattavan koodin, sijoittaa sen taulukkoon ja palauttaa tämän taulukon
paluuarvona.
- Metodi, joka kysyy käyttäjältä tämän arvauksen, sijoittaa numerot taulukkoon ja palauttaa
tämän taulukon paluuarvona.
- Metodi, joka selvittää arvauksen tuloksen ja tulostaa sen perusteella vihjeen.


Olen hahmotellut jotain seuraavaa Notepad++:ssa:

class ohjelmointitesti10{

public static void main(String[] agrs){

int [] uusikoodi=koodi();
int[] veikkauskoodi=arvaus();
tulosvihje(uusikoodi, veikkauskoodi);


}
//arpoo arvattavan koodin ja, sijoittaa sen taulukkoon ja palauttaa taulukon
public static int[] koodi()
{
int [] oikeakoodi = new int [6];
for (int i=1; i<6; i++)
{
	oikeakoodi[i]=1+(int)(Math.random()*9);
}
return (oikeakoodi);
}


// kysyy käyttäjältä arvauksen, sijoittaa numerot taulukkoon ja palauttaa taulukon
public static int[] arvaus()
{

	int j;
	int[] arvattukoodi = new int [6];



	for (j=1; j<6; j++)
	{

		System.out.println("Anna "+j+" luku:");
		arvattukoodi[j]=Lue.kluku();

	}
		return (arvattukoodi);
}





//tulostaa rivit
public static void tulostus(int[] rivi)
{
	for(int i=1; i<6; i++)
		System.out.print(rivi[i]+"\t");
	System.out.println();
}

//arvauksen tulos ja tulostaa vihjeen

public static int tulosvihje(int[] realcode, int [] guess)
{

	int i, j,summa=0;
for(i=1; i<6; i++)
		for(j=1; j<6; j++)
			if(realcode[1]==guess[1]) summa++;
		if(realcode[2]==guess[2]) summa++;
		if(realcode[3]==guess[3]) summa++;
		if(realcode[4]==guess[4]) summa++;
		if(realcode[5]==guess[5]) summa++;
		System.out.println("Vihje:  "+summa);
		return (summa);




}

}

Metabolix [26.11.2021 22:56:38]

#

Tuo on hyvä alku. Olet tehnyt jo vaikeimmat kohdat koodista lähes oikein.

Alkuun eli main-metodiin pitää lisätä se ohjelman idea: laita käyttäjän lukujen kysyminen ja tarkastaminen silmukkaan, ja jos luvut ovat oikein, lopeta silmukka. Tässä yksi mahdollisuus on, että tulosvihje-metodissa jätetään vihje tulostamatta silloin, kun kaikki luvut ovat oikein (eli määrä on viisi), mutta palautetaan kuitenkin se oikeiden määrä. Silloin ei tarvitse tehdä erikseen taulukon tarkastusta main-metodiin vaan voi siellä vain katsoa, palauttaako tulosvihje oikeiden määräksi viisi.

Tulosvihje sisältää tällä hetkellä turhat (ja virheelliset) for-silmukat, kun tarkistat jokaisen kohdan eillisellä if-lauseella. Siellä pitäisi varmasti olla vain yksi for-silmukka (ihan kuten arvonnassa ja tulostuksessa), ja silmukan sisällä if-lauseella tarkistettaisiin, onko kohdassa i oleva numero oikea. Jos numero on oikea, pitää lisätä summaan kyseinen numero ja lisäksi määrään yksi, ja vihjeessä pitää näyttää määrä ja summa.

Arvontasi tuottaa nyt numeroita 1–9, eli nolla puuttuu. Miten korjaisit tämän?

Ohjeessa neuvotaan, että taulukossa olisi viisi alkiota. Jos haluat tehdä ohjeen mukaan, pitää vaihtaa taulukoissa ja silmukoissa kuutosen tilalle viitonen ja silmukoissa lisäksi ykkösen tilalle nolla, jotta käydään läpi kohdat 0–4 eikä 1–5. Tietysti myös nykyinen versio toimii, siinä vain on taulukoissa yksi ylimääräinen kohta (0).

Voisit myös sisentää koodin siistimmin, nyt tuossa rivit hyppivät, miten sattuu.

Jere Sumell [27.11.2021 12:28:16]

#

Oma kassakaapin turvakoodin arvausohjelmisto on tässä: Kiva, jos saat tästä jotain vinkkiä tai uutta näkokulmaa ohjelmointiisi tulevaisuutta silmällä pitäen.

import java.util.Random;
import java.util.Scanner;

public class Kassakaappi {

	private static Random r = new Random();
	private static Scanner sc = new Scanner(System.in);
	private static int[] turvakoodi = new int[5];


	public static int[] arvaus(int[] arvattu) {
		int[] ret = new int[2];
		int matches = 0;
		int sum=0;
		for (int x=0;x<turvakoodi.length;x++) {
			if (turvakoodi[x] == arvattu[x]) {
				System.out.println(""+x +" -"+arvattu[x]);
				matches++;
				sum+=arvattu[x];
			}
		}
		ret[0] = matches;
		ret[1] = sum;
		return ret;
	}

	public static void arvoTurvakoodi() {
		int next = 0;
		for (int x=0;x<turvakoodi.length;x++) {
			next = r.nextInt(10);
			turvakoodi[x] = next;
		}

	}

	public static void tulostaTulos(int[] arra) {
		for (int x=0;x<arra.length ;x++) {
			System.out.println("" +arra[x]);
		}
	}

	public static void main(String[] args) {
		arvoTurvakoodi();
		/*System.out.println("Kassakaappi on lukittu uudella turvakoodilla. Avaa kassakaappi arvaamalla oikea turvakoodi.");
		tulostaTulos(turvakoodi);*/
		int tries = 0;
		String in="";
		int[] tulos = new int[2];
		do {

		int[] arvaus = new int[turvakoodi.length];

		for (int x=0;x<arvaus.length;x++) {
			System.out.println("[" +(x+1)+"]");
			in = sc.nextLine();
			arvaus[x] = Integer.parseInt(in);
		}
		tulos = arvaus(arvaus);
		tries++;
		tulostaTulos(tulos);
		if (tulos[0] == turvakoodi.length) {
			System.out.println("Sait kassakaapin auki! Käytit " +tries +" yrityskertaa! Oikea turvakoodi on:");
			tulostaTulos(arvaus);
		}
		} while (tulos[0] == turvakoodi.length || !in.equalsIgnoreCase(""));


	}
}

Jere Sumell [27.11.2021 13:05:58]

#

Jos jatkan vielä tuota itse keksimääni kontekstia tuohon numeronarvauspeliin tuon kassakaapin osalta, niin jos on jokin viisinumeroinen pin-koodi, niin brute-forcea ehkä nopeampi tapa selvittää oikea koodi on käydä merkki kerrallaan ne koodin alkiot läpi.

Tässä nyt tällainen Kassakaappikeikka -esimerkki, millä saa nopeasti kassakaapin 5-numeroisen turvakoodin murrettua ilman bruteforcea, raakaa laskentatehoa, koska jos ajatellaan jotain kassakaappimiehiä, jotka ottaneet kohteekseen jonkin arvojalokiviä ja harvinaisia uniikkeja kuubalaisia käsinvalmistettuja cohiba-sikareita sisältävän kassakaapin, niin aika on kriittinen, että kaapin sisllon saa tyhjennettyä ennen kuin poliisit ehtii paikan päälle, eli siis kassakaappi täytyy saada mahdollisimman nopeasti koneellisesti auki.

import java.util.Random;


public class Kassakaappikeikka {

	private static Random r = new Random();
	private static int[] turvakoodi = new int[5];
	private static int tries;

	public static String murra(int alkio) {
		for (int x= 0;x<=9;x++) {
			tries++;
			if (turvakoodi[alkio]== x) {
				return "[" +x +"]-" +x;
			}
		}
		return "" +alkio +". arvo murrettu!";
	}

	public static void arvoTurvakoodi() {
		int next = 0;
		for (int x=0;x<turvakoodi.length;x++) {
			next = r.nextInt(10);
			turvakoodi[x] = next;
		}

	}

	public static void tulosta(int[] arra) {
		for (int x=0;x<arra.length ;x++) {
			System.out.print (" " +arra[x]);
		}
	}

	public static void main(String[] args) {
		arvoTurvakoodi();
		tries =0;
		System.out.println("Kassakaappi on lukittu uudella turvakoodilla. Avaa kassakaappi murtamalla oikea turvakoodi.");

		for (int x=0;x<turvakoodi.length;x++) {
			murra(x);
		}
		System.out.println("Kassakaappi aukeni! Tarvittiin " +tries +" kierrosta turvakoodin selvittämiseen!");
		tulosta(turvakoodi);
	}

}

Tämä kassakaappikeikka-esimerkki on ihan fiktion tuotetta, en kannusta ketään hämärämiehen polulle en netissä enkä oikeassa elämässä.

LateKuusila [28.11.2021 12:48:22]

#

Kiitos vinkeistä. Nyt hieman olen muokannut koodia seuraavanlaiseksi (nuo rivien tulostukset alussa vain itselleni helpottamaan kokeilua ja tekemistä):

class ohjelmointitesti11{

public static void main(String[] agrs){

int [] uusikoodi=koodi();
int[] veikkauskoodi=arvaus();
tulosvihje(uusikoodi, veikkauskoodi);
tulostus(uusikoodi);
tulostus(veikkauskoodi);
 while(uusikoodi!=veikkauskoodi)
 {
	 arvaus();
	 tulosvihje(uusikoodi, arvaus());
 }


}

public static int[] koodi()
{
int [] oikeakoodi = new int [5];
for (int i=0; i<5; i++)
{
	oikeakoodi[i]=0+(int)(Math.random()*9);
}
return (oikeakoodi);
}



public static int[] arvaus()
{
	int j;
	int[] arvattukoodi = new int [5];
	for (j=0; j<5; j++)
	{

		System.out.println("Anna "+(j+1)+" luku:");
		arvattukoodi[j]=Lue.kluku();

	}
		return (arvattukoodi);
}




public static void tulostus(int[] rivi)
{
	for(int i=0; i<5; i++)
		System.out.print(rivi[i]+"\t");
	System.out.println();
}

public static void tulosvihje(int[] realcode, int [] guess)
{

	int i, j,summa=0, oikeatsumma=0;
for(i=0; i<5; i++)

			if(realcode[i]==guess[i]){
				summa++;
				oikeatsumma=oikeatsumma+guess[i];
			}
		/**if(realcode[1]==guess[1])
		{summa++;
	oikeatsumma=oikeatsumma+guess[1];
		}
		if(realcode[2]==guess[2])
		{summa++;
	oikeatsumma=oikeatsumma+guess[2];
		}
		if(realcode[3]==guess[3]){
			summa++;
			oikeatsumma=oikeatsumma+guess[3];
		}
		if(realcode[4]==guess[4])
		{summa++;
	oikeatsumma=oikeatsumma+guess[4];
		}**/
		System.out.println("Vihje:  "+summa+", "+oikeatsumma);


}

}

Ongelmana on seuraava: Nyt silmukka tulostaa vihjeen vain joka toinen kerta, eli kysyy ensin luvut 1-5 kaksi kertaa, sitten tulostaa vihjeen. Vihje myös joskus on ihan "päätön", eli esim. "Vihje: 7, 29". Mistä tämä mahtaa kiikastaa?

Kiitos asiallisista ja hyvistä vastauksista aloittelevalle!

jalski [28.11.2021 13:35:14]

#

Olisikohan seuraavilla riveillä jotain tekemistä asian kanssa (huomioi kuinka monta kertaa arvaus() esiintyy):

 while(uusikoodi!=veikkauskoodi)
 {
	 arvaus();
	 tulosvihje(uusikoodi, arvaus());
 }

Olisikohan Javalla ohjelmoidessa joku fiksumpi tapa ottaa tuo koodin syöte kuin merkki kerrallaan? Itse lukisin koodin kerralla, splittaisin ja muuntaisin numero taulukoksi.

LateKuusila [28.11.2021 13:39:23]

#

Äsken naputeltu seuraavaan muotoon. Nyt vihje tulostuu oikeanlaisena, joskin taas kahden yrityksen jälkeen ja arvaukset-laskurin toiminta hieman vielä hämärän peitossa. Jatkan yrittämistä...

class ohjelmointitesti11{

public static void main(String[] agrs){

int [] uusikoodi=koodi();
 int[] veikkauskoodi=arvaus();
int arvaukset=tulosvihje(uusikoodi,veikkauskoodi);

 while (arvaukset<5)
 {

	arvaus();
	tulosvihje(uusikoodi, arvaus());

 }

}

public static int[] koodi()
{
int [] oikeakoodi = new int [5];
for (int i=0; i<5; i++)
{
	oikeakoodi[i]=0+(int)(Math.random()*9);
}
return (oikeakoodi);
}



public static int[] arvaus()
{
	int j;
	int[] arvattukoodi = new int [5];
	for (j=0; j<5; j++)
	{

		System.out.println("Anna "+(j+1)+" luku:");
		arvattukoodi[j]=Lue.kluku();

	}
		return (arvattukoodi);
}




public static void tulostus(int[] rivi)
{
	for(int i=0; i<5; i++)
		System.out.print(rivi[i]+"\t");
	System.out.println();
}

public static int tulosvihje(int[] realcode, int [] guess)
{

	int i, j,summa=0, oikeatsumma=0, arvaukset=1;
for(i=0; i<5; i++)

	arvaukset++;
			if(realcode[i]==guess[i]){
				summa++;
				oikeatsumma=oikeatsumma+guess[i];
			}

				if (summa<5)
				{
				System.out.println("Vihje:  "+summa+", "+oikeatsumma);
				}
				if (summa==5)
				{
					System.out.println("Arvauksia tarvittiin: "+arvaukset);
				}


		return summa;

}

}

jalski [28.11.2021 13:44:01]

#

LateKuusila kirjoitti:

Äsken naputeltu seuraavaan muotoon. Nyt vihje tulostuu oikeanlaisena, joskin taas kahden yrityksen jälkeen ja arvaukset-laskurin toiminta hieman vielä hämärän peitossa. Jatkan yrittämistä...

Eikö Java oikeasti edes varoita, että käytät funktiota aliohjelmana? (Funktio siis palauttaa arvon ja aliohjelma ei) Katsopa hieman tarkemmin tuota laittamaani kohtaa koodissa ja kuinka monta kertaa arvaus() esiintyy...

Jere Sumell [28.11.2021 19:19:53]

#

Oletko Late Turun Yliopiston tietojenkäsittelyn perusopinnoissa nyt suorittamassa niitä kenties? Tuli mieleeni kysyä, kun aloitin itse avoimen väylän kautta 2005 loppuvuodesta ne, ja siellä oli silloin jo käytössä tuo sinun käyttämäsi Lue -staattinen luokkakirjasto, että opiskelijoiden ei tarvitse heti alkuun opetella esimerkiksi tuota Scanner -luokan ilmentymän käyttöä.

Voihan tuo olla Lue-kirjastoluokka olla muissakin oppilaitoksissa laajemmassakin käytössä, en tiedä. Itse törmäsin siihen Turun Yliopiston perusopintokurssin ohjelmoinnin perusteet -kurssilla.

En tiedä, kun koronan takia loppui tekniikan laitoksella FM-tutkinnossa opinto-oikeus, mitä sain tietojenkäsittelyn tradenomitutkinnon jälkeen sitä kaksi vuotta, kun tuotti ongelmia, kun korona sotki pakan, kun meni etänä kursseja, niissähän ei ole sellaista kollektiivista yhteisöllsyyttä, mitä sitten ihan lähiopetus-metodeilla järjestetyissä luentotilaisuuksissa.

Varmaan otan yhteyttä sinne opintotoimistoon, jos he ottavat minut ensi syksyn hausa vielä huomioon siinä haussa iästäni huolimatta, niin voisi tehdä tutkinnon loppuun vaikka huvin vuoksi, tietojenkäsittelytieteissä kuitenkin ihan mielenkiintoisia aiheita, joista saisi sen Pro Gradu -tutkielman laadituksi, mikä on se FM-linjan opinnäytetyö, jonka jälkeen saa sitten maisterin paperit ulos.

Kannattaa muuten olla käyttämättä noissa for-silmukan lopetusehdoissa kovakoodattuja numeroita, itse suosin tuota .lenght -attribuutin kutsua, niin ei tarvitse sitten miettiä, kuinka monta alkiota taulukko sisälsikään. En tiedä, miten tuo while-silmukkasi päättyy tuossa "while (arvaukset<5)", tullaanko siitä koskaan ulos lohkon päättävän aaltosulkeen jälkeen seuraavalle koodiriville suorittamaan sitä, kun siinähän ei koskaan kasvateta tuota muttujan arvoa, mitä siinä testataan. arvaukset++ tai arvaukset+=1 tai arvaukset = arvaukset+1 silmukan loppuun, vai miten arvo inkrementointuu se jäi vähän epäselväksi.

neosofta [28.11.2021 19:36:43]

#

Vaikkakin Java oksettaa ja Turussa on ainoastaan yksi hyvä puoli eli tienviitta Tampereelle niin missähän vaiheessa Late tuossa koodissaan tuo/luo Lue luokan ilmentymän, instanssin?

Jere Sumell [28.11.2021 19:41:48]

#

Ei sitä instanssia tarvitse luodakaan, kun luokkakirjastoissa kaikki metodit on siinä metodin otsikkorivillä määritelty static -avainsanalla, niin silloin metodin kutsu tapahtuu <Tietotyyppi>.metodinNimi(Syöteparametrit), eli Lue.kluku() -esimerkiksi, kuten Late aivan oikein sitä osaa käyttää, niinkuin pitääkin.

neosofta [28.11.2021 19:44:00]

#

Aivan sama, mutta entäs toi tienviittaus sitten?

Jere Sumell [28.11.2021 21:11:11]

#

On se hyvä, että te Tamperelaisetkin osaatte täältä suunnistaa kotiinne. Tampereen moottoritiehän sinne teille johtaa. Ei mulla mitään Tamperetta vastaan ole, ihan ok kaupunki, olen useasti kesä-aikaan käynyt siellä.

Pirkkalan lentoaseman B-terminaali kyllä kalpenee Turun lentoasemalle, aika kämäinen paikka. Empiirinen kokemus lojaaleista taksikuskeista sunnuntai-maanantain puolen yön jälkeen hiljaisina ajoaikoina, ja onhan se totta, että Tampereella sijaitsee tiedotusopin laitos, ja perinteisesti työväen teatteri-kulttuuritoiminta on paremmalla tolalla, mitä täällä kotikaupungissani Turussa, ja onhan Tampereella varmaan vielä nykyäänkin ihan ok suomirock, tai manserock -skene uuden polven tekijät, mitä siellä Juice, Mikko Alatalo ja Harri Rinne tutustuivat, ja loivat pohjan myöhemmille tekijöille.

Hakametsän jäähallissakin tullut käytyä Tappara-TPS -ratkaisevassa finaalissa, jonka me voitimme, ja eilenhän siellä pelattiin Tapparan osalta viimeinen kotimatsi, ja Ilves hävisi oman viimeisen Hakametsän hallin historian pelin juuri TPS:lle perjantaina.

Onhan se perinteinen vastakkainasettelu ja vitsailu Turku-Tampere -akselin osalta, mutta en ota osaa siihen. Tampere on ihan ok! En itsekään pidä kaikilta osin kotikaupunkini Turun poliittisesta ilmapiiristä, koska se on liian sininen.

LateKuusila [29.11.2021 09:52:18]

#

Vaasassa kauppatieteitä, nyt tjt perusopinnot valinnaisena.

Taas on tullut koodia muokkailtua, nyt näyttää seuraavalta. Ongelmana vielä se, että kaikkien lukujen ollessa oikein ei tulosta tuota "Arvauksia tarvittiin", vaan tulostaa "Vihje: 5, xx" ja jatkaa sen jälkeen lukujen kysymistä.

public class ohjelmointitesti100
{
	public static void main(String[] agrs)
	{

		int[] koodi = GeneroiKoodi();
		int[] arvaus;
		int arvaustenMaara = 0;
		boolean Ratkaistu = false;

		//Näyttää luvut. Poista kun koodi toimii
		tulostus(koodi);

		//Toistetaan kunnes ratkaistu
		while(Ratkaistu != true)
		{
			arvaustenMaara++;
			arvaus = ArvaaKoodi();
			tulostus(arvaus); //TODO: poista kun input toimii
			Ratkaistu = Tarkista(koodi,arvaus);
		}

		if(Ratkaistu == true)
		{
			System.out.println("Arvauksia tarvittiin: " + arvaustenMaara);
		}
	}

	// -- Luo viisinumeroisen koodin -- //
	public static int[] GeneroiKoodi()
	{
		int [] uusikoodi = new int [5];
			for (int i = 0; i < uusikoodi.length; i++)
			{
				uusikoodi[i] = 0 + (int)(Math.random()*9);
			}
		return (uusikoodi);
	}

	// -- Arvataan lukua -- //
	public static int[] ArvaaKoodi()
	{
		int[] arvattukoodi = new int [5];
		for (int j = 0; j < arvattukoodi.length; j++)
		{
			System.out.println("Anna "+(j+1)+"numero");
			arvattukoodi[j] = Lue.kluku();
			//Integer.parseInt(console.readLine("Anna "+(j+1)+" luku:"));
		}
		return (arvattukoodi);
	}

	// -- Tulostus -- //
	//Tulostaa listan luvut peräkkäin
	public static void tulostus(int[] rivi)
	{
		for(int i = 0; i< rivi.length; i++)
		{
			System.out.print(rivi[i] + " ");
			System.out.println();
		}
	}

	public static boolean Tarkista(int[] Ratkaisu, int[] yritys)
	{
		//Tarkoituksena tulostaa kaksi lukua, kun arvaus väärin:
		//Oikeiden lukujen määrän ja oikeiden lukujen summa.

		//Aloittaa laskemalla oikeiden kokonaismäärä ja summa
		int oikeat = 0;
		int summa = 0;

		for(int i = 0; i < Ratkaisu.length; i++)
		{
			if(Ratkaisu[i] == yritys[i])
			{
				oikeat++;
				summa += yritys[i];
			}
		}

		//Jos kaikki oikein
		if(summa == Ratkaisu.length)
		{
			return true;
		}else
			System.out.println("Vihje: " + oikeat + ", " + summa);
			return false;

	}
}

Jere Sumell [29.11.2021 10:32:48]

#

Hienoa, että otit tuon .lenght-attribuutin kutsun käyttoon noissa for-toistorakenteiden lopetusehdoissa.

Tuollainen huomio, että muuttujien nimet eivät oikeaoppisesti määriteltynä ala isolla kirjaimella, toisin kuin Tietotyyppien eli luokan nimi alkaa isolla, mutta muuttujien tyypit eivät ala isolla kirjaimella. Nythän sinulla alkaa tuo boolean Ratkaistu, isolla "R" -kirjaimella. Korjaa se.

Sitten taas, jos määrittelee muuttujan final -varatulla sanalla, jolloin muuttujan arvoa ei pysty enää muuttamaan, niin siinä tapauksessa muuttujan nimi kirjoitetaan kaikki isolla kirjaimella.

if-ehtolauseen vertailukohtana on aina boolean, joten riittää pelkästään

if (Ratkaistu)

ja sitten while-silmukan ehto

while (!ratkaistu)
{
...

TapaniS [29.11.2021 12:43:17]

#

LateKuusila kirjoitti:

Taas on tullut koodia muokkailtua, nyt näyttää seuraavalta. Ongelmana vielä se, että kaikkien lukujen ollessa oikein ei tulosta tuota "Arvauksia tarvittiin", vaan tulostaa "Vihje: 5, xx" ja jatkaa sen jälkeen lukujen kysymistä.

Lopetusehdossa verrataan oikein arvattujen lukujen summaa ratkaisutaulukon alkioiden lukumäärään. Koodi siis pysähtyy, kun oikein arvattujen lukujen summa on 5, mikä ei yleensä toteudu, jos kaikki luvut on arvattu oikein.

Kun yritin kääntää koodin, niin antoi virheen, että Lue.kluku(); ei löydy.

neosofta [29.11.2021 13:24:47]

#

TapaniS kirjoitti:

, että Lue.kluku(); ei löydy

Joo, ei löydy jos et ko. luokkaa erikseen ymppää testiisi... Kuten Jere Sumell jo aiemmin mainitsikin, niin voit käyttää sen asemesta esim. Scanner -luokkaa

import java.util.Scanner;

//...

public static int[] ArvaaKoodi()
{
    int[] arvattukoodi = new int [5];
    Scanner Lue = new Scanner(System.in);
    for (int j = 0; j < arvattukoodi.length; j++)
    {
        System.out.println("Anna "+(j+1)+". numero:");
        arvattukoodi[j] = Integer.valueOf(Lue.nextLine());
    }
    return (arvattukoodi);
}

Late@
Olet tosi lähellä... jännitys tiivistyy

Jere Sumell [29.11.2021 18:21:50]

#

TapaniS kirjoitti:

Kun yritin kääntää koodin, niin antoi virheen, että Lue.kluku(); ei löydy.

Opiskele humaani historiaa ja näin nettimaailmassa käy koko säikeen historia läpi ennen postaustasi vastineeksi alkuperäiselle.

Toi Lue -on staattsia metodeita omaava luokkakirjasto, mikä mun ymmärryksen laajentumisen myötä on lähtenyt myös Turun yliopistosta eteenpäin, tai en tiedä onko se laajentunut tänne, mutta jos luet koko tämän säikeen läpi, niin vastaus löytyy kyllä, miksi et löytänyt tuota Lue - instanssia mistään.

Kannatta olla loggautunut sisään yliopsiton Moodle-ympäristöön, näin nykyisellään jos ajattelen, mikää se on. Vaikka olen juonut neljättä päivää puolta litraa kotamaista makrotalousjuomaa ja vielä on kesken tämän illan riitti ja mnossa koko ajan. Totoa sentään pelasin suomitammoja. Mun suosikkeja.

carabia [29.11.2021 19:09:28]

#

Jere Sumell kirjoitti:

Opiskele humaani historiaa...

Jere Sumell kirjoitti:

Vaikka olen juonut neljättä päivää puolta litraa kotamaista makrotalousjuomaa...

Kirjoittaja on varoittava esimerkki "humaani historian" opiskelemisesta.
Otetaan jere ihan iisisti, jookoskookos?

neosofta [29.11.2021 20:04:43]

#

Joo, jottei menisi aivan liian jännittäväksi...

Late@
Kokeile miten pitkälle pääset tekemällä edelliseen versioosi seuraavat pari pientä muutosta:

public class ohjelmointitesti100
{

    public static void main(String[] agrs)
    {

        // ...

        while(!Ratkaistu)
        {
            arvaustenMaara++;
            arvaus = ArvaaKoodi();
            // lykätään yksi parametri perään...
            Ratkaistu = Tarkista(koodi,arvaus,arvaustenMaara);
        }

        // ...
    }

    // ...

    // ja myös tänne yksi parametri perään...
    public static boolean Tarkista(int[] ratkaisu, int[] yritys, int yritykset)
    {

        int oikeat = 0;

        for(int i = 0; i < ratkaisu.length; i++)
        {
            if(ratkaisu[i] == yritys[i])
            {
                oikeat++;
            }
        }
        // eli jos kaikki meni putkeen...
        if(oikeat == ratkaisu.length)
        {
            return true;
        }
        else
        {
            System.out.println("Vihje - oikeita:" + oikeat + ", yrityksiä:" + yritykset);
            return false;
        }

    }
}

Jere voi sitten puhtaaksikirjoittaa, kunhan ensin selviää...

Jere Sumell [30.11.2021 13:52:18]

#

Tein joitain muutoksia koodiin, lähinnä muutin muuttujien etukirjaimet pieniksi, ja luokan nimen vaihdoin, ja tietotyypin alkukirjain on nyt isolla, ja korvasin tuon Lue.kluku() -metodin Scannerilla. Kommentoin koodiin kohdat, jotka poistat ja mihin kohtaan korvaat sen Lue.kluku(), jos tykkäät käyttää sitä. Lisäksi siistisin tuon koodin tulostusmetodin siten, että koodi tulostuu siistimmin, eli tuo tyhjä System.out.println() for-silmukan ulkopuolelle sen jälkeen. Lisäksi lisäsin tuonne tarkista-metodiin tuon oikeiden arvausten summan laskemisen ja lopuksi tulostusriville summan tulostuksen tottakai.

Valmis koodi:

import java.util.Scanner;

public class Arvauspeli
{
	public static void main(String[] agrs)
	{

		int[] koodi = GeneroiKoodi();
		int[] arvaus;
		int arvaustenMaara = 0;
		boolean ratkaistu = false;

		//Näyttää luvut. Poista kun koodi toimii
		tulostus(koodi);

		//Toistetaan kunnes ratkaistu
		 while(!ratkaistu)
	        {
	            arvaustenMaara++;
	            arvaus = ArvaaKoodi();
	            // lykätään yksi parametri perään...
	            ratkaistu = tarkista(koodi,arvaus,arvaustenMaara);
	        }

		if(ratkaistu == true)
		{
			System.out.println("Arvauksia tarvittiin: " + arvaustenMaara);
		}
	}

	// -- Luo viisinumeroisen koodin -- //
	public static int[] GeneroiKoodi()
	{
		int [] uusikoodi = new int [5];
			for (int i = 0; i < uusikoodi.length; i++)
			{
				uusikoodi[i] =  (int)(Math.random()*9);
			}
		return (uusikoodi);
	}

	// -- Arvataan lukua -- //
	public static int[] ArvaaKoodi()
	{
		Scanner s = new Scanner(System.in);	//poista tämä, jos tykkäät käyttää Lue.kluku()

		int[] arvattukoodi = new int [5];
		for (int j = 0; j < arvattukoodi.length; j++)
		{
			System.out.println("Anna "+(j+1)+" numero");

			arvattukoodi[j] = s.nextInt();	//Korvaa tähän Lue.kluku
			//Integer.parseInt(console.readLine("Anna "+(j+1)+" luku:"));
		}
		return (arvattukoodi);
	}

	// -- Tulostus -- //
	//Tulostaa listan luvut peräkkäin
	public static void tulostus(int[] rivi)
	{
		for(int i = 0; i< rivi.length; i++)
		{
			System.out.print(rivi[i] + " ");

		}
		System.out.println();
	}

	   public static boolean tarkista(int[] ratkaisu, int[] yritys, int yritykset)
	    {

	        int oikeat = 0;
	        int summa = 0;

	        for(int i = 0; i < ratkaisu.length; i++)
	        {
	            if(ratkaisu[i] == yritys[i])
	            {
	                oikeat++;
	                summa+= yritys[i];
	            }
	        }
	        // eli jos kaikki meni putkeen...
	        if(oikeat == ratkaisu.length)
	        {
	            return true;
	        }
	        else
	        {
	            System.out.println("Vihje - oikeita:" + oikeat + ", yrityksiä:" + yritykset + " Oikeiden summa:" +summa);
	            return false;
	        }

	    }
}

EDIT 30.11.2021 18:36
Poistin jalskin toivomuksesta tuon turhan nollan tuosta 0-9 -arvon arvonnasta koodin generointimetodista, kun pistin tämän valmiin ohjelman toimintakuntoisena lähdekoodin kokonaisuudessaan tänne, ja minulla on tämä muokkausoikeus tähän, niin ei tarvitse duplikaatisti tämän takia enää leikepöydältä copy-pastettaa koko koodia uudestaan tuon takia.

TapaniS [30.11.2021 16:06:21]

#

Hei, nyt käännös meni läpi ja koodi toimii!

Tosin kone arpoo nyt numeroita väliltä 0 .. 8. Tätä ei nyt erikseen tehtävässä mainittu, mutta varmaan tuo 9 voisi olla myös mukana.

Jere Sumell [30.11.2021 17:03:14]

#

No tuo ysin saaminen mukaan korjaantuu helposti, kun vaihtaa tuon Math.random kertoimen 9->10, niin sitten arvoja arvotaan väliltä 0-9

// -- Luo viisinumeroisen koodin -- //
public static int[] GeneroiKoodi()
{
	int [] uusikoodi = new int [5];
		for (int i = 0; i < uusikoodi.length; i++)
		{
			uusikoodi[i] = 0 + (int)(Math.random()*10);	//9->10 muutos
		}
	return (uusikoodi);
}

Jos käyttäisi tuota Java.util.Random -luokkaa, kuten alunperin esitin tuossa Kassakaappi -luokassani, niin sittenhän ei tarvitse tehdä pakotettua tyyppimuunnosta intiksi, mutta tässä Late valinnut käyttää tuota Math-luokan staattista random() -metodia, jonka palauusarvo on liukuluku, double.

Sellaisessakin voisi olla ideaa loppukäyttäjän mielenkiinnon säilyttämiseksi ja sen ylläpitämisen edistämisen porkkanana, että tuolla tarkista-metodissa tulostettaisiin arvatut numerot, niin sitten on jotain lähdettä olemassa, mistä voi päätellä kun ohjelma tulostaa oikeiden arvausten summan, että voi vähän tehdä päätelmiä, mitkä arvoista olivat oikeita mahdollisesti ja mitkä eivät, jolloin mahdollisesti lopullinen koodi ratkeaa vähemmillä ratkaisuyrityskerroilla.

jalski [30.11.2021 17:52:33]

#

Jere Sumell kirjoitti:

No tuo ysin saaminen mukaan korjaantuu helposti, kun vaihtaa tuon Math.random kertoimen 9->10, niin sitten arvoja arvotaan väliltä 0-9

// -- Luo viisinumeroisen koodin -- //
public static int[] GeneroiKoodi()
{
	int [] uusikoodi = new int [5];
		for (int i = 0; i < uusikoodi.length; i++)
		{
			uusikoodi[i] = 0 + (int)(Math.random()*10);	//9->10 muutos
		}
	return (uusikoodi);
}

Jos käyttäisi tuota Java.util.Random -luokkaa, kuten alunperin esitin tuossa Kassakaappi -luokassani, niin sittenhän ei tarvitse tehdä pakotettua tyyppimuunnosta intiksi, mutta tässä Late valinnut käyttää tuota Math-luokan staattista random() -metodia, jonka palauusarvo on liukuluku, double.

Mutta mitä tuo nolla tuossa tekee, miksi nollaan lisätään arvottu luku?

Jere Sumell [30.11.2021 18:12:18]

#

Nolla on kyllä turha, sanoisin tuossa kohtaa. Tuo Math.random() arpoo jonkin liukuluvun väliltä 0.0-1.0 positiivisella etumerkillä, joten vaikka nollan poistaa tuosta lausekkeen edestä, niin lopputulos lienee sama?

jalski [30.11.2021 18:28:22]

#

Jere Sumell kirjoitti:

Nolla on kyllä turha, sanoisin tuossa kohtaa. Tuo Math.random() arpoo jonkin liukuluvun väliltä 0.0-1.0 positiivisella etumerkillä, joten vaikka nollan poistaa tuosta lausekkeen edestä, niin lopputulos lienee sama?

Sitä vähän ihmettelin, miksei kukaan ole korjannut? 😄

Jere Sumell [30.11.2021 18:39:54]

#

Muutin sen tuohon postauksen koodiin, missä on tuo valmis ja toimiva Arvauspeli -luokka -ja ohjelman lähdekoodi esitetty, että ei tarvitse leikepöydältä koko ohjelman koodia tuon yhden nollan poiston takia enää leikepöydältä tänne liittää uudestaan. Hakukoneet ei tykkää indeksoida sivustoja, jotka sisältävät duplikaatteeja.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta