package cz.beranek.model;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
import cz.beranek.model.akcniKarty.BalicekFinance;
import cz.beranek.model.akcniKarty.BalicekNahoda;
import cz.beranek.model.herniPlan.HerniPlan;
import cz.beranek.model.herniPlan.IArtikl;
import cz.beranek.model.herniPlan.IPole;
import cz.beranek.model.herniPlan.Kun;
import cz.beranek.projekt.Zpravy;
public class Hra {
private SeznamHracu hraci;
private Hrac host;
//private HerniPlan herniPlan;
private BalicekNahoda kartyNahoda;
private BalicekFinance kartyFinance;
private SeznamMajetku seznamMajetku;
private ObsazeniDostihu obsazeniDostihu;
private boolean hraBezi = false;
private boolean koupenyKun = false;
private boolean koupenyDostihy = false;
public static final int CASTKA_POCATECNI = 30000;
public static final int CASTKA_START = 4000;
/**Sleduje zmeny atributu Hracu*/
private PropertyChangeListener propertyChangeListener;
private PaymentListener paymentListener;
private Random random;
public Hra() {
/*ReloadableResourceBundleMessageSource rrbms = new ReloadableResourceBundleMessageSource();
rrbms.setResourceLoader(new ResourceLoader() {
@Override
public Resource getResource(String arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public ClassLoader getClassLoader() {
// TODO Auto-generated method stub
return null;
}
})*/
hraci = new SeznamHracu();
seznamMajetku = new SeznamMajetku();
obsazeniDostihu = new ObsazeniDostihu();
kartyNahoda = new BalicekNahoda();
kartyFinance = new BalicekFinance();
random = new Random();
propertyChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if(evt.getPropertyName().equals("ready")){
System.out.println(evt.getSource() + " hlasi pripraven.");
boolean allReady = true;
for (Hrac h : hraci.values()) {
allReady &= h.isReady();
}
if (allReady) {
Zpravy.presmeruj(Hra.this, "hra.start");
}
}else if(evt.getPropertyName().equals("pozice")){
//TODO
Hrac h = (Hrac)evt.getSource();
Zpravy.odesliPoziciHrace(Hra.this, h, h.getPozice() + 1);
}else if(evt.getPropertyName().equals("penize")){
//TODO zmena penez (JK upravil)
Hrac h = (Hrac)evt.getSource();
//Zpravy.odesliHraciZpravu(h, "Stav pen�z hr��e " + h.getNick() + ": " + h.getPenize());
Zpravy.odesliStavPenez(Hra.this, h, h.getPenize());
}else if(evt.getPropertyName().equals("gameLoaded")){
System.out.println(evt.getSource() + " hlasi nacteni hry.");
boolean allLoaded = true;
for (Hrac h : hraci.values()) {
allLoaded &= h.isGameLoaded();
}
if (allLoaded) {
start();
}
}
}
};
paymentListener = new PaymentListener() {
@Override
public void paymentMade(PaymentEvent evt) {
if (evt.isSuccessful()) {
// X zaplatil hraci Y Z
StringBuilder sb = new StringBuilder(evt.getPayer()
.getNick());
sb.append(" zaplatil");
if (evt.getPayee() != null)
sb.append(" hr��i ").append(evt.getPayee().getNick());
else
sb.append(" bance");
sb.append(" ").append(evt.getAmount()).append(" DP.");
Zpravy.odesliVsemZpravu(Hra.this, sb.toString());
System.out.println(evt);
}else{
Zpravy.odesliHraciZpravu(evt.getPayer(), "Nedostatek pen�z, chyb� V�m " + (evt.getAmount() - evt.getPayer().getPenize()));
}
}
};
}
/** vrati pocet hracu*/
public int vratPocetHracu() {
return hraci.vratPocetHracu();
}
/**Odstartuje hru.*/
private void start(){
Zpravy.odesliVsemZpravu(this, "Hra za��n�!");
hraci.seradNahodne();
for (Hrac hrac : hraci.values()) {
hrac.setPenize(CASTKA_POCATECNI);
hrac.postupNa(0);
}
hraBezi=true;
Zpravy.odesliHraceNaTahu(this, hraci.naTahu());
hodKostkou(hraci.naTahu());
}
/**Ukonceni tahu hrace a preskoceni na dalsiho hrace na tahu.
* @param hrac
* @return
*/
public boolean konecTahu(Hrac hrac){
if(hrac != hraci.naTahu()) return false;
koupenyKun = false;
koupenyDostihy = false;
//TODO Konec hry?
Hrac naTahu = hraci.dalsi();
while(naTahu.getZdrzujeSe() > 0 || naTahu.podezreniZDopingu == true){
naTahu.setZdrzujeSe(Math.max(0, naTahu.getZdrzujeSe() - 1));
naTahu.podezreniZDopingu = false;
Zpravy.odesliVsemZpravu(this, naTahu.getNick() + " toto kolo nehraje.");
naTahu = hraci.dalsi();
}
Zpravy.odesliHraceNaTahu(this, hraci.naTahu());
//TODO: Moznost vsadit pred hodem
hodKostkou(hraci.naTahu());
return true;
}
/**Hod kostkou hrace na tahu.
* @param hrac
*/
private void hodKostkou(Hrac hrac){
if(hrac != hraci.naTahu()) return;//AH Pro jistotu to tu necham.
int kostka = kostka();
if (hrac.getPozice() == HerniPlan.DISTANC) {
Zpravy.odesliVsemZpravu(this, hrac.getNick() + " hodil " + kostka + ".");
if ( kostka == 6) {
Zpravy.odesliVsemZpravu(this, hrac.getNick() + " opustil pole Distanc.");
kostka = kostka();
} else {
Zpravy.odesliVsemZpravu(this, hrac.getNick() + " z�st�v� na poli Distace.");
return;
}
}
if (kostka == 6) kostka += kostka(); //Neni potreba hlasit 6, staci celkem.
Zpravy.odesliVsemZpravu(this, hrac.getNick() + " hodil " + kostka+".");
if (kostka == 12) {
hrac.postupNa(HerniPlan.DISTANC);
Zpravy.odesliVsemZpravu(this, hrac.getNick() + " jde na distance ");
} else {
boolean presStart = hrac.postupO(kostka);
if(presStart)hrac.pridatPenize(CASTKA_START);
IPole pole = HerniPlan.getPole(hrac.getPozice());
//to asi nebudem posilat..staci onformace kolik hodil a kolik plati
//Zpravy.odesliVsemZpravu(this, "Hr�� " + hrac.getNick() + " postoupil na pole " + pole.getNazevPole());
pole.proved(this, hrac, kostka);
}
}
/** Zakoupeni artiklu zastoupeneho polickem, na kterem hrac stoji.
* @param hrac
* @return
*/
public int kupPole(Hrac hrac) {
IPole p = HerniPlan.getPole(hrac.getPozice());
if (p instanceof IArtikl){
IArtikl a = (IArtikl) p;
Hrac majitel = getSeznamMajetku().getMajitel(a);
if (majitel != null){
return 10;
}
boolean zaplaceno = hrac.zaplat(null, a.getNakupniCena());
if (!zaplaceno) {
return 20;
}
getSeznamMajetku().setMajitel(a, hrac);
koupenyKun = true;// Nakup se tyka pole, na kterem hrac stoji, neni treba rozlisovat typ pole.
Zpravy.odesliVsemZpravu(this,
a.getNazevArtiklu() + " nyn� pat�� hr��i " + hrac.getNick());
}
return 0;
}
/**Nakup dostihu pro kone, na kterem hrac stoji.
* @param hrac
* @param pocet
* @return
*/
public int kupDostihy(Hrac hrac, int pocet){
IPole p = HerniPlan.getPole(hrac.getPozice());
if (p instanceof Kun){
Kun k = (Kun) p;
//Kontrola vlastnictvi staje
boolean vlastniStaj = true;
for (Kun kun : k.getStaj()) {
vlastniStaj &= getSeznamMajetku().getMajitel(kun) == hrac;
}
if(!vlastniStaj){
return 10;
}
//Kontrola nakupu ihned po zakoupeni kone
if(koupenyKun){
return 30;
}
//Kontrola poctu dostihu
//5 je max
int kd = getObsazeniDostihu().getDostihy(k);
if (kd == 5){
return 20;
}
//Prek koupenim HD musi byt koupeny 4
int newKd = kd + pocet;
if(kd < 4 && newKd == 5){
return 21;
}
//Krajni meze, nemelo by se stat
if(pocet < 0 || newKd > 5){
return 22;
}
//Pri nesouvislem nakupu vice dostihu
if(koupenyDostihy && newKd == 5){
return 23;
}
//Platba
boolean zaplaceno = hrac.zaplat(null, pocet * k.getCenaDostihu());
if (!zaplaceno){
//nedostatek penez
return 100;
}
getObsazeniDostihu().setDostihy(k, newKd);
koupenyDostihy = true;
}
return 0;
}
/** Proda bance dany pocet dostihu za polovinu porizovaci ceny.
* Je-li pocet prodavanych dostihu vyssi nez stavajici pocet dostihu kone,
* budou prodany vsechny dostihy kone.
* @param hrac Kvuli overeni majitele, jinak neni potreba.
* @param kun
* @param pocet
* @return
*/
public int prodejDostihy(Hrac hrac, Kun kun, int pocet){
if (hrac != getSeznamMajetku().getMajitel(kun)) return 10;//Hrac neni majitelem kone
if (pocet < 0 || pocet > 5) return 20; //Neplatny pocet dostihu (to je spis na vyjimku)
int after = getObsazeniDostihu().getDostihy(kun) - pocet;
after = Math.max(0, after);
getObsazeniDostihu().setDostihy(kun, after);
return 0;
}
/** Prodej artiklu jinemu hraci nebo bance za smluvenou castku, resp. porizovaci cenu.
* @param artikl Prodavana polozka
* @param komu Jiny hrac, nebo null, prodava-li hrac artikl bance.
* @param zaKolik
* @return
*/
public int prodejArtikl(IArtikl artikl, Hrac komu, int zaKolik){
Hrac majitel = getSeznamMajetku().getMajitel(artikl);
if (majitel == null)
return 1; // Majitelem je banka
if (majitel == komu)
return 2; // Nelze prodad sam sobe
if(artikl instanceof Kun){
Kun k = (Kun) artikl;
int pd = 0;
for (Kun kun : k.getStaj()) {
pd += getObsazeniDostihu().getDostihy(kun);
}
if(pd > 0) return 3; //Nelze prodat cast staje s obsazenym dostihem.
}
if(komu == null){
majitel.pridatPenize(artikl.getNakupniCena());
getSeznamMajetku().setMajitel(artikl, null);
}else {
boolean zaplaceno = komu.zaplat(majitel, zaKolik);
if(zaplaceno){
getSeznamMajetku().setMajitel(artikl, komu);
}else{
return 4; //Nedostatek penez
}
}
return 0;
}
/** Prodej vice artiklu jinemu hraci nebo bance za smluvenou castku, resp. porizovaci cenu.
* Nelze prodat cast staje, kde jsou obsazeny dostihy.
* @param artikl Prodavana polozka
* @param komu Jiny hrac, nebo null, prodava-li hrac artikl bance.
* @param zaKolik
* @return
*/
public int prodejArtikly(Hrac kdo, Hrac komu, Collection<IArtikl> co, int zaKolik){
if(co.isEmpty()) return 10; //Nic k prodeji
List<IArtikl> copy = new ArrayList<IArtikl>(co);
int cena = 0;
for (IArtikl artikl : copy) {
final Hrac majitel = getSeznamMajetku().getMajitel(artikl);
if(majitel != kdo)
return 21; //prodejce neni majitelem vsech polozek
if (majitel == null)
return 22; // Majitelem je banka
if (majitel == komu)
return 23; // Nelze prodad sam sobe
//Kontrola prodeje casti staje
if(artikl instanceof Kun){
final Kun k = (Kun) artikl;
final Set<Kun> staj = k.getStaj();
int pd = 0;
for (Kun kun : staj) {
pd += getObsazeniDostihu().getDostihy(kun);
}
if(pd > 0 && !copy.containsAll(staj)) {
return 30; //Nelze prodat cast staje s obsazenym dostihem.
}
copy.removeAll(staj);
}else{
copy.remove(artikl);
}
cena += artikl.getNakupniCena();
}
//Platba
if(komu == null){
kdo.pridatPenize(cena);
}else {
boolean zaplaceno = komu.zaplat(kdo, zaKolik);
if(!zaplaceno){
return 40; //Nedostatek penez
}
}
//Prepsani majetku
for (IArtikl a : co) {
getSeznamMajetku().setMajitel(a, komu);
}
return 0;
}
public Hrac getHost() {
return host;
}
public void setHost(Hrac host) {
this.host = host;
}
public Hrac getHrac(String klic) {
return hraci.get(klic);
}
public SeznamHracu getHraci() {
return hraci;
}
public void addHrac(String klic, Hrac hrac) {
hrac.addPropertyChangeListener(propertyChangeListener);
hrac.addPaymentListener(paymentListener);
hraci.put(klic, hrac);
}
private int kostka(){
return random.nextInt(6) + 1;
}
public SeznamMajetku getSeznamMajetku() {
return seznamMajetku;
}
public ObsazeniDostihu getObsazeniDostihu() {
return obsazeniDostihu;
}
public BalicekNahoda getKartyNahoda() {
return kartyNahoda;
}
public BalicekFinance getKartyFinance() {
return kartyFinance;
}
public boolean hraBezi() {
return hraBezi;
}
}