Log in

View Full Version : Quick help programmazione C++/C#



Madeiner
2nd July 2011, 21:07
Ciao, sto sbattendo la testa con sta cosa...
E' sicuramente una cavolata ma non ne esco fuori.

E' la funzione di un robot che deve caricarsi, e a volte sta trasportando una batteria.
Se la sua batteria è scarica, oppure se sta trasportando una batteria e quella è scarica, allora deve ricaricarsi.

if ((energyCell.energyLevel < remfuel ) or (this.load.energyLevel < 1)) {
caricabatterie();
}

Ora, a volte this.load.energyLevel semplicemente non esiste, perchè il robot sta trasportando un altra cosa o non sta trasportando nulla. Se questo accade, il programma si pianta dicendo che energylevel non è una categoria valida, mentre io vorrei che semplicemente continasse.

Vorrei scrivere una cosa che dica "se this.load.energyLevel esiste, ed è minore di 1"
Ma non so come fare.

Potrei ovviamente fare una struttura del tipo:

If "sto trasportando batteria"
|
| if (controlla batteria E carico) caricabatterie();
|
else (controlla solo la batteria del robot) caricabatterie();

Ma mi sembra una soluzione orribile...

Any help?

Eltarion
2nd July 2011, 22:05
if !(this.load.energyLevel == null)

Il fatto è che non è detto che energyLevel sia inizilaizzata a null, se mi dai la definizione vediamo che tipo è.

Kat
2nd July 2011, 22:08
Aggiungi nell'if la condizione (this.load != null) in and a this.load.energyLevel < 1.
Inoltre ti serve la condizione se load e' una batteria che non saprei come scrivere non sapendo che tipo e' load.
In C# lo puoi controllare scrivendo if (this.load is TipoBatteria).

Madeiner
2nd July 2011, 22:39
Dunque... la soluzione if !(this.load.energyLevel == null) non sembra funzionare
Dice che this.load.energyLevel è sconosciuto
Nel debug this.load è null (il robot non ha carico).
"energyLevel" dovrebbe essere una variabile (non so il termine corretto) della classe EnergyCell (la batteria).

Load è la variabile che indica il carico del bot. Va da se che null.energylevel non esiste... quindi si pianta.

Kat... non ho capito bene cosa hai detto :P

Però mi hai fatto venire in mente di scrivere cosi:

if ((energyCell.energyLevel < treshold ) or (this.load == null) or (this.load.category != PowerCell) or (this.load.energyLevel < 1)) {

e sembra funzionare! (anche se rimane brutto. In sostanza funziona solo xke gli OR sono ordinati in quel modo credo)


Energycell cmq è definito cosi:

This information is special, because it returns the information about another object, in this case the power pack. This means that energyCell contains all the characteristics of a normal object, for example category (PowerCell or NuclearCell), position (the position of the cell), etc.
If you want to know the energy level of a robot, you must not check energyLevel, but energyCell.energyLevel.
If the bot has bot no power cell, energyCell returns null.

Dr.Doomed
3rd July 2011, 00:02
Dunque... la soluzione if !(this.load.energyLevel == null) non sembra funzionare
Dice che this.load.energyLevel è sconosciuto
Nel debug this.load è null (il robot non ha carico).
"energyLevel" dovrebbe essere una variabile (non so il termine corretto) della classe EnergyCell (la batteria).

Load è la variabile che indica il carico del bot. Va da se che null.energylevel non esiste... quindi si pianta.

Kat... non ho capito bene cosa hai detto :P

Però mi hai fatto venire in mente di scrivere cosi:

if ((energyCell.energyLevel < treshold ) or (this.load == null) or (this.load.category != PowerCell) or (this.load.energyLevel < 1)) {

e sembra funzionare! (anche se rimane brutto. In sostanza funziona solo xke gli OR sono ordinati in quel modo credo)


Energycell cmq è definito cosi:

This information is special, because it returns the information about another object, in this case the power pack. This means that energyCell contains all the characteristics of a normal object, for example category (PowerCell or NuclearCell), position (the position of the cell), etc.
If you want to know the energy level of a robot, you must not check energyLevel, but energyCell.energyLevel.
If the bot has bot no power cell, energyCell returns null.

Kat ti stava dicendo che non basta verificare che load sia NULL, perche potrebbe anche capitare che load sia, che ne so, un mattone e difficilmente un mattone ha un campo energyLevel definito.
Circa il blocco if, lo strutturerei cosi`
if (energyCell.energyLevel < treshold ){
caricabatterie();
}
elseif ((this.load != null) AND (this.load.category == EnergyCell) AND (this.load.energyLevel < 1)) {
caricabatterie();
}

Come l'hai scritto tu effettivamente e` brutto, ma soprattutto (mi pare) sbagliato perche` ricarichera` sempre le batterie a prescindere, eccetto quando il robot ha la sua batteria carica e il carico e` nullo oppure diverso da EnergyCell, nel qual caso ti dovrebbe cacciare il solito errore.

Ma poi, PowerCell e` diverso da EnergyCell? :scratch:

PS: con AND intendo shotcircuit "and" operator (il "&&" di java, non il "&"), altrimenti il problema si ripresenta

Madeiner
3rd July 2011, 00:29
Come l'hai scritto tu effettivamente e` brutto, ma soprattutto (mi pare) sbagliato perche` ricarichera` sempre le batterie a prescindere, eccetto quando il robot ha la sua batteria carica e il carico e` nullo oppure diverso da EnergyCell, nel qual caso ti dovrebbe cacciare il solito errore.


Si hai ragione, me ne sono accorto poi dopo.
Ho modificato cosi:

if ((energyCell.energyLevel < treshold ) and ((this.load == null) or (this.load.category != PowerCell)) or (this.load.energyLevel < 1)) {

che mi pare funzioni. Ma vabè queste son cose di logica su cui poi ragiono.





Ma poi, PowerCell e` diverso da EnergyCell? :scratch:


Bella domanda... la documentaazione è quella che è. Il resto è in francese...
Cmq, da quel che ho capito, una "batteria" può essere una Powercell o una Nuclearcell, come oggetto fisico.

Energycell è la categoria di queste due batterie.
energylevel è una variabile (again, non ricordo il nome) che hanno gli oggetti di categoria energycell.

PS: Cmq sto usando Colobot. E' interessante e divertente!

Hardcore
3rd July 2011, 03:04
energy level può avere come valore -1?

Se non è cosi puoi istanziare energy level a -1 di default, e mettere
this.load.energyLevel ==0 al posto di this.load.energyLevel < 1

Kat
3rd July 2011, 09:44
Si hai ragione, me ne sono accorto poi dopo.
Ho modificato cosi:
if ((energyCell.energyLevel < treshold ) and ((this.load == null) or (this.load.category != PowerCell)) or (this.load.energyLevel < 1)) {
che mi pare funzioni. Ma vabè queste son cose di logica su cui poi ragiono.

Questa condizione che hai scritto pero non fa quello che hai chiesto all'inizio, invece e' corretta quella postata da Dr.Doomed.
Oppure non ti sei spiegato bene :D

Hador
3rd July 2011, 10:45
dal punto di vista architetturale accedere direttamente a qualcosa che può non esistere è una porcata. Non avere nel sistema uno stato che caratterizzi il trasporto e il tipo di trasporto è un'altra porcata.

sicuramente tutti i possibili oggetti caricati dovrebbero implementare un'interfaccia che impone l'esistenza di un metodo che ti ritorni il tipo. Tipo LoadedObject.getType(); che ritorna "Battery" piuttosto che "Brick". A sto punto fai un handler che casta l'oggetto caricato al tipo esatto e puoi gestire i metodi specifici per ogni oggetto. L'idea è che se il robot può trasportare cose diverse e se per ogni oggetti sono implementabili comportamenti complessi rispetto all'oggetto questo deve essere modellato decentemente (ad esempio con uno Strategy method). In questo modo tu definisci tale strategia quando sai che sicuramente ha in mano una batteria, evitando problemi vari, e se volessi aggiungere comportamenti complessi rispetto ad altri oggetti trasportati non avresti problemi.

Architetturalmente, il robot si può trovare in diversi stati e tu a livello di codice dovresti rappresentarlo. Questi stati (fermo, in movimento, trasporto oggetto ecc) hanno associato a loro comportamenti specifici (quando è fermo si può muovere, quando ha la batteria deve controllarne il livello di carica ecc) e dovresti rappresentare il tutto.

Se poi stai programmando il roombla per fare le capriole e non te ne fotte un cazzo è un altro discorso :sneer:

Madeiner
3rd July 2011, 16:12
energy level può avere come valore -1?
Se non è cosi puoi istanziare energy level a -1 di default, e mettere
this.load.energyLevel ==0 al posto di this.load.energyLevel < 1
Purtroppo no, energylevel deve essere tra 0 e 1. Nemmeno null è riconosciuto come valido. E non credo di poter modificare il valore io stesso...

Questa condizione che hai scritto pero non fa quello che hai chiesto all'inizio, invece e' corretta quella postata da Dr.Doomed.
Oppure non ti sei spiegato bene :D
Mi spiegheresti xke? Io pensavo che quell'if poteva tradursi in:
if ((energyCell.energyLevel < treshold ) and ((this.load == null) or (this.load.category != PowerCell)) or (this.load.energyLevel < 1)) {
Se la batteria del robot è scarica E (il carico non è una batteria, o è nullo)
OPPURE
Se la batteria trasportata è scarica.
A me interessa che il robot vada a caricarsi quando una delle due batterie è scarica. Non è corretta quella struttura?

Io credo che funzioni xke qualcuno ha menzionato la parola "shortcircuit" prima, me la sono cercata, e questo linguaggio funziona proprio cosi: entra nell'IF alla prima condizione valida, quindi mettendo quell'OR alla fine, non si pianta quando il carico non è una batteria.


dal punto di vista architetturale accedere direttamente a qualcosa che può non esistere è una porcata. Non avere nel sistema uno stato che caratterizzi il trasporto e il tipo di trasporto è un'altra porcata.
sicuramente tutti i possibili oggetti caricati dovrebbero implementare un'interfaccia che impone l'esistenza di un metodo che ti ritorni il tipo. Tipo LoadedObject.getType();

Vero.. non credo ci sia un metodo del genere :( D'altronde è un software semplice...


A sto punto fai un handler ...
Se poi stai programmando il roombla per fare le capriole e non te ne fotte un cazzo è un altro discorso :sneer:
Questo pezzo ti ho perso :P In realtà sto programmando dei robottini semplici, quindi si alla fine non me ne frega molto, anche se lo sto facendo per imparare, quindi cerco di evitare le soluzioni brutte o non realistiche.
In sostanza ci sono una serie di robottini che possono interagire in un mondo, navigare, raccogliere e muovere oggetti, combattere (è la parte piu difficile da programmare), fare le gare, giocare a calcio, ste cose qui...
Per dire, gia programmare un robot per organizzare dei materiali in una superficie quadrata è un impresa, se si considera che gli altri robot devono poter accedere ai materiali prendendone uno a caso :P
(Organizzandoli in una linea, invece, ci sono riuscito)

Hador
3rd July 2011, 16:15
ma sta roba dove la hai presa scusa? cioè non ho capito è un lavoro, un esempio, università, un libro... ?

Dr.Doomed
3rd July 2011, 16:59
Mi spiegheresti xke? Io pensavo che quell'if poteva tradursi in:
if ((energyCell.energyLevel < treshold ) and ((this.load == null) or (this.load.category != PowerCell)) or (this.load.energyLevel < 1)) {
Se la batteria del robot è scarica E (il carico non è una batteria, o è nullo)
OPPURE
Se la batteria trasportata è scarica.
A me interessa che il robot vada a caricarsi quando una delle due batterie è scarica. Non è corretta quella struttura?
Io credo che funzioni xke qualcuno ha menzionato la parola "shortcircuit" prima, me la sono cercata, e questo linguaggio funziona proprio cosi: entra nell'IF alla prima condizione valida, quindi mettendo quell'OR alla fine, non si pianta quando il carico non è una batteria.


(
(1)________(energyCell.energyLevel < treshold )
and
________(
(2a)____________(this.load == null)
________or
(2b)____________(this.load.category != PowerCell)
________)
or
(3)________(this.load.energyLevel < 1)
)


Ma che succede se il robotino e` scarico, ma trasporta una batteria completamente carica?
L'impressione e` che
(1)= true,
(2a)= false,
(2b) = false,
(3)= false
ovvero
true AND (false OR false) OR false
ovvero
true AND false OR false
il che ritorna false, e quindi niente carica.


ma sta roba dove la hai presa scusa? cioè non ho capito è un lavoro, un esempio, università, un libro... ?

Parlava di colobot, credo sia questo giochino:
http://www.ceebot.com/colobot/index-e.php

Madainer, non capisco se ti ci trastulli per gioco o se hai ambizioni maggiori.

Kat
3rd July 2011, 17:57
Mi spiegheresti xke? Io pensavo che quell'if poteva tradursi in:
if ((energyCell.energyLevel < treshold ) and ((this.load == null) or (this.load.category != PowerCell)) or (this.load.energyLevel < 1)) {
Se la batteria del robot è scarica E (il carico non è una batteria, o è nullo)
OPPURE
Se la batteria trasportata è scarica.
A me interessa che il robot vada a caricarsi quando una delle due batterie è scarica. Non è corretta quella struttura?
Inizialmente hai detto:
Se la sua batteria è scarica, oppure se sta trasportando una batteria e quella è scarica, allora deve ricaricarsi.

Quindi:
if ((energyCell.energyLevel < treshold ) or (this.load!=null and this.load.category==PowerCell and this.load.energyLevel < 1))

In particolare:
energyCell.energyLevel < treshold indica se la batteria e' scarica

this.load!=null indica se sta trasportando qualcosa
this.load.category==PowerCell indica se sta trasportando una batteria
this.load.energyLevel < 1 indica se la batteria che trasporta e' scarica

Che poi e' la stessa cosa che ha scritto Dr.Doomed solo compressa in una sola espressione invece di usare elseif al posto dell'or.

Madeiner
3rd July 2011, 18:26
Ma che succede se il robotino e` scarico, ma trasporta una batteria completamente carica?


Capito l'errore, grazie! Fail di logica da parte mia



Madainer, non capisco se ti ci trastulli per gioco o se hai ambizioni maggiori.


Eh, tra un po devo iniziare a seguire corsi di programmazione per l'uni, volevo portarmi un po avanti, poi i robot mi sono sempre interessati, ed è un modo leggero per imparare (anche xke se no col cavolo che ci passerei 3-4 ore al giorno come sto facendo). Quindi diciamo 50 e 50.



Inizialmente hai detto:
Se la sua batteria è scarica, oppure se sta trasportando una batteria e quella è scarica, allora deve ricaricarsi.

Quindi:
if ((energyCell.energyLevel < treshold ) or (this.load!=null and this.load.category==PowerCell and this.load.energyLevel < 1))


Capito l'errore! Tnx! Tutta roba utile per capire la logica che ci sta dietro