Co mi się bardziej opłaca praca w UK czy w PL

March 1st, 2015

Tyle się pierdoli o kwocie wolnej od podatków… postanowiłem zatem sprawdzić kilka rzeczy i porównać średnią stawkę z PL do tej z UK.

Założenia i narzędzia

By takie porównanie miało sens należy założyć kilka rzeczy.

  • Jako podstawę wyliczeń przyjmuję stawkę godzinową senior java deva dla górnych 10% zarobków. W przypadku stawki dziennej zakładam, że jest ona proporcjonalna do 8 godzin pracy.
  • Interesuje mnie stosunek kwoty po opodatkowaniu (PIT, ZUS, NFZ + odpowiedniki z UK) do kwoty z umowy.
  • Kwota z umowy to jest średnia stawka razy 168 (godzin) albo dzienna razy 21 (dni).
  • Traktuję ta kwotę jako kwotę zarobioną na UoP ponieważ porównywanie się jako firma nie ma sensu.

Teraz czas na narzędzia. Do wyliczenia podatków w UK użyłem narzędzia Listen To Taxman. Narzędziem dla Polski będzie kalkulator płac money.pl.

Końcowy wynik otrzymam dzieląc kwotę netto (net) przez brutto (gross).

Źródła danych

Skoro wiemy już co chcemy policzyć i za pomocą czego to liczymy czas na dobranie się do danych. Dla Wielkiej Brytanii dane pobrałem z portalu It job watch.
Z Polską maiłem trochę większy problem, bo nie ma tu dobrego źródła informacji (raport SiS jest wątpliwy). Jako średnią stawkę godzinową dla senior java dev przyjąłem 85PLN bazując na ogłoszeniach z 4p i nofluffjob.

Wyliczanki

Jako, że matematykę robią za nas narzędzia to tylko pozwolę sobie na omówienie wyników cząstkowych bez wgłębiania się w wyliczenia.

Ile zarabiamy dziennie, miesięcznie, rocznie

W UK stawka dzienna to 625 funtów.
W PL stawka dzienna to 680 złotych.

W UK stawka miesięczna to 13125 funtów.
W PL stawka miesięczna to 14280 złotych.

W UK stawka roczna to 157500 funtów.
W PL stawka roczna to 171360 złotych.

Jak widać nie ma tu dużych różnic zakładając, że ceny podstawowych produktów i usług są na podobnym poziomie. Oczywiście założenie jest nie do końca poprawne, bo o ile spożywka w UK jest stosunkowo tania to już usługi są droższe. Można jednak przyjąć, że zarobki na tym poziomie zarówno w UK jak i PL kwalifikują nas do klasy średniej.

Czas na wyliczanki

Płaca roczna netto w UK wyniesie 94116,72 funtów.
Płaca roczna netto w PL wyniesie 117820,99 złotych.

Wygląda nieźle policzmy zatem proporcje

Stosunek płacy netto do brutto w UK wynosi 94116.72/157500=0.59756647619
Stosunek płacy netto do brutto w PL wynosi 117820,99/171360=0.68756413398

Zatem jak widać robiąc to samo w UK i korzystając z wyższej kwoty wolnej oddam państwu około 9% więcej.

Janusze na swoim

Na koniec jeszcze króciutkie wyliczenie dla Januszy na swoim, którzy łapią się już w normalny ZUS. Kwota miesięczna to kwota na FV. Podatek liniowy. Średni miesięczny koszt to 1000PLN (biuro, księgowość, paliwo, amortyzacja, zakupy książek i elektroniki). Do wyliczeń posłużę się tym kalkulatorem zysku.

Kwota netto miesięcznie po odliczeniu wszelkich kosztów to 10226.05PLN.
Kwota netto rocznie po odliczeniu wszelkich kosztów to 122712.60PLN.

Stosunek netto rocznie do brutto to 10226.05*12/171360=0.71610994397

Przy czym wyliczenie nie uwzględnia jeszcze około 2,5 tysiąca, które wynika z odliczania VAT z faktur kosztowych. Po uwzględnieniu stosunek rośnie do 0.73.

Jak zatem widać na załączonym obrazku gadka o podwyższaniu kwoty wolnej to populizm w swojej najczystszej postaci.

Wkurw – najlepszy motywator do działania

February 24th, 2015

Jak zapewne niektórzy pamiętają w zeszłym roku popełniłem tu tekst na temat tworzenia konwerterów Vaadin za pomocą lambd. Dziś na blogu Vaadin pojawił się wpis gdzie był link do dodatku, który robi coś podobnego… przy czym robi to strasznie chujowo, bo traci część funkcjonalności.

Zrobiło mi się po ludzku przykro… ja tu piszę tekst w którym wyjaśniam co i jak, a tu taka niespodzianka… no ale bywa…

Przy okazji pojawił się Vaadin w wersji 7.4 i mamy tam w końcu poprawioną tabelkę co się nazywa teraz Grid. W demówce na stronie Vaadin jest używany specyficzny renderer, który pozwala na generowanie ikon z Font Awesome. Przy czym nie ma nigdzie kodu tego renderera. No wkurwiłem się strasznie, bo potrzebuję tego na wczoraj, a sam komponent rozwiązał mi dużo problemów…

Postanowiłem więc napisać własny renderer, który jest dostępny na githubie FontAwesomeRenderer. Dużo jeszcze tam pracy, ale generalnie wszem i wobec ogłaszam kod jest kurwa mój i żadna pizda w rurkach nie podpierdoli go już. Howgh!

Klucz

February 23rd, 2015

Krótko i filozoficznie.

Jaki nośnik jest najtrwalszy? Papier. Przy odpowiednich warunkach przechowywania można będzie go odczytać i za tysiąc lat. Dwa warunki. Będziemy znali alfabet oraz język. Nie jest to trudne do spełnienia, bo zapewniają nam to słowniki, które starają się uwspółcześnić język.

Chciałem zagrać w LHX. Nie mam stacji dyskietek 3,5″ czytającej w standardzie HD (1.44mb). Raptem 10 lat temu miałem… i mogłem zgrać…. choć LHX-a miałem też na na 5.25″. Za 20 lat nie odczytam danych z mojego dysku, bo ext3 nie będzie wspierany…

Kluczem do przyszłości jest stworzenie mechanizmów pozwalających na odczytywanie przeszłości.

Spring Boot szybkie wprowadzenie książkowe

February 22nd, 2015
Learning Spring Boot

Tytuł: Learning Spring Boot
Autor: Greg L. Turnquist
Rok: 2014
ISBN: 978-17-843-9302-1

Oj dobra książka dobra. Szczególnie jak chcesz się nauczyć Spring Boot. Same tutoriale z sieci i dokumentacja są OK, ale czasami warto sięgnąć po coś bardziej “mięsnego”. I taka właśnie jest ta książka.

Oczywiście zanim do niej usiądziesz musisz znać co nieco Javę i przynajmniej mieć pojęcie o Springu jako takim.

Co się z niej dowiesz?
Jak zainstalować, skonfigurować i uruchomić aplikację Spring Boot… ale to oczywiste :) Jednak forma w jakiej autor przedstawił ten temat jest naprawdę warta uwagi. Nie ograniczył się tylko do typowych przypadków, ale też opisał pewne podstawowe błędy, które można popełnić. Moim zdaniem można tą książkę traktować jako coś w rodzaju “manual by example”.

I na koniec szpila. Jest kilka drobnych błędów, ale można je wyłapać o ile ogarnia się springa.

—–

Really good book. If you think that tutorials and docs in network are good but you looking for something “more” this is book for you. Before you start you should know something about Java nad Spring.

What you will know after reading?

How to setup, configure and run spring boot. It is obvious ;) But in my opinion way how author presents that is very good. It simple, logical and cover most of common cases (and wrote some words about exceptional cases). You can treat as a “manual by example”.

Finally I found some small mistakes and inconsistency in examples but as I wrote at beginning you should know about spring and then you can easily recognize this issues.

Co ja zrobiłem między tagami, czyli szybki changelog w git

February 9th, 2015

Musiałem napisać maila do klienta z wykazem zmian w aplikacji od ostatniego wdrożenia. Czyli taki zwyczajny changelog.
Pamiętać wszystko co się działo nie sposób. Jest jednak na to metoda.

Trzymam się konwencji związanej z pracą ze zgłoszeniami na bitbuckecie. Inaczej mówiąc w wiadomościach do commitów zamieszczam odpowiednie słówka sterujące tak by móc manipulować zgłoszeniami. Przykładowo umieszczenie w wiadomości fixed #666 zamknie zgłoszenie o podanym numerze. Gdy zrobimy push
To czasami lubi się wywalać (nie odpala hooka), ale generalnie działa OK.

Konwencja pozwala na zrobienie czegoś takiego:

Listing 1. Polecenie generujące changelog

git log v0.3...v0.4 --pretty=format:'%H %s' | grep 'fixed #'

i już mamy wykaz zamkniętych zgłoszeń. Bawiąc się grepem i formatem można z tego wyprodukować htmla do wstawienia na stronę. Jedynym istotnym elementem jest podanie nazw tagów (w przykładzie v0.3…v0.4) by mieć zakres. Bez tego dostaniemy wszystkie commity.

Jeżeli spodobał ci się ten wpis to podziel się nim ze znajomymi korzystając z przycisków poniżej. Do tego one służą.

Nawigacja w Vaadin z użyciem Guice

February 7th, 2015

I kolejny temat około pracowy mi wyszedł. Zaczęło się od tweeta:

I generalnie tu pojawił się pomysł na wpis.

Problem

Chcemy by nasze View w Vaadin mogły być tworzone w taki sposób by Guice mógł wstrzyknąć im np. serwisy. Najprościej jest to zrobić w następujący sposób:

Listing 1. Wykorzystanie zdarzeń

public class NavigationProvider implements Provider<Navigator> {

	@Inject
	private MyUI ui;

	@Inject
	private ViewRegister viewRegister;

	@Inject
	private Provider<Injector> injector;

	@Override
	public Navigator get() {
		Navigator nav = new Navigator(ui, ui);
		viewRegister.initNavigation(nav);
		nav.addViewChangeListener(new ViewChangeListener() {
			@Override
			public boolean beforeViewChange(ViewChangeEvent event) {
				injector.get().injectMembers(event.getNewView());
				return true;
			}

			@Override
			public void afterViewChange(ViewChangeEvent event) {

			}
		});
		return nav;
	}
}

Mamy tu trzy zasadnicze elementy. Po zerowe obiekty Navigation są dostarczane providerem do głównego UI. Po pierwsze wstrzykujemy UI po utworzeniu providera (i wstrzyknięciu go do UI). Zrobienie tego w konstruktorze jest OK, ale jakieś takie niekoszerne i wymaga kombinowania.
Po drugie potrzebujemy instancji injectora i wstrzykujemy go przez providera.
Po trzecie po utworzeniu Navigation dodajemy do niego listener, w którym mając już utworzony nowy widok wstrzykujemy w niego potrzebne składowe. ViewRegister to już ciekawostka, do budowania “zagłębień” w menu.

Wadą tego rozwiązania jest brak możliwości tworzenia widoków wykorzystujących wstrzykiwanie przez konstruktor. Wynika to z faktu, że w bebechach Vaadin wykorzystywany jest ClassBasedViewProvider, który poprzez refleksję tworzy nowe widoki. By to działało narzuca on ograniczenie z bezparametrowym konstruktorem.

To czy wykorzystywać wstrzykiwanie przez konstruktor czy też przez pola to problem na osobą dyskusję. W każdym razie ja trafiłem na sytuację gdy wstrzykiwanie przez konstruktor okazało się zdroworozsądkowe.

Rozwiązanie

Kto śledzi bloga ten zapewne kojarzy mechanizm Assisted Injection obecny w Guice. Kliknijcie poczytajcie. Do rozwiązania naszego problemu wykorzystam właśnie ten mechanizm.

Własny Navigation

W sumie nie własny, bo rozszerzający ten z Vaadin, ale zawsze:

Listing 2. Ta klasa ma straszną nazwę…

public class GuicefiedNavigator extends Navigator {

	private GuiceViewProviderFactory guiceViewProviderFactory;

	@Inject
	public GuicefiedNavigator(GuiceViewProviderFactory guiceViewProviderFactory,
	                          @Assisted UI ui, @Assisted SingleComponentContainer container) {
		super(ui, container);
		this.guiceViewProviderFactory = guiceViewProviderFactory;
	}

	@Override
	public void addView(String viewName, Class viewClass) {
		Preconditions.checkNotNull(viewName, "view and viewClass must be non-null");
		Preconditions.checkNotNull(viewClass, "view and viewClass must be non-null");
		removeView(viewName);
		addProvider(guiceViewProviderFactory.create(viewName, viewClass));
	}

}

Jeden konstruktor, który akurat potrzebuję (bonus AI – można mieć wiele konstruktorów oznaczonych @Inject) i który jest zmapowany w odpowiedniej fabryce:

Listing 3. Ta nazwa jest bardzo javowa

public interface GuicefiedNavigatorFactory {

	GuicefiedNavigator create(UI ui, SingleComponentContainer container);
}

nadpisujemy tu jedną metodę. Służy ona to dodawania widoków i ich providerów do mechanizmu nawigacji. W oryginale jest to wykorzystana jak wspomniałem klasa ClassBasedViewProvider. Ja zastąpiłem ją za pomocą GuiceViewProviderFactory

I jeszcze GuiceViewProvider

Skoro jest factory to mamy tu kanapkę z podwójnym mięskiem, czyli kolejny AI na pokładzie.

Listing 4. Pracuję nad nazwami

public class GuiceViewProvider implements ViewProvider {

	private Provider<Injector> injectorProvider;

	private String viewName;

	private Class viewClass;

	@Inject
	public GuiceViewProvider(Provider<Injector> injectorProvider,
	                         @Assisted String viewName, @Assisted Class viewClass) {
		this.injectorProvider = injectorProvider;
		this.viewName = checkNotNull(viewName);
		this.viewClass = checkNotNull(viewClass);
	}

	@Override
	public String getViewName(String navigationState) {
		if (null == navigationState) {
			return null;
		}
		if (viewName.equals(navigationState)
				|| navigationState.startsWith(viewName + "/")) {
			return viewName;
		}
		return null;
	}

	@Override
	public View getView(String viewName) {
		if (this.viewName.equals(viewName)) {
			return injectorProvider.get().getInstance(viewClass);
		}
		return null;
	}
}

Tu magii nie ma (jest za to factory). Wstrzykujemy injector, z którego później pobieramy nowe instancje widoków.

Konfiguracja

Ostatnim krokiem w tej zabawie jest skonfigurowanie tego wszystkiego by śmigało jak należy dodać odpowiedni wpis w konfiguracji modułów.

Listing 5. Guice 3.0 w akcji w środowisku 4.0

install(new FactoryModuleBuilder().
		implement(GuicefiedNavigator.class, GuicefiedNavigator.class)
		.build(GuicefiedNavigatorFactory.class));                    
install(new FactoryModuleBuilder().                                  
		implement(GuiceViewProvider.class, GuiceViewProvider.class)  
		.build(GuiceViewProviderFactory.class));

Podsumowanie

Są dwie pułapki w tym całym rozwiązaniu. Po pierwsze kwestia sprawdzenia nazw w GuiceViewProvider musi spełniać kontrakt z interfejsu. Jednak nie ma tam słowa o tym slashu. Po drugie należy pamiętać, że wszystkie widoki musimy bindować jako bez scopa, bo domyślny singleton zrobi nam sieczkę z aplikacji (nie wiem jak to działa, bo z obserwacji wynika duża losowość).

Jeżeli spodobał ci się ten wpis to podziel się nim ze znajomymi korzystając z przycisków poniżej. Do tego one służą.

System rezerwacji sal – część 0 – co chcę zrobić

January 25th, 2015

Mam pomysł na apkę z serii “do poćwiczenia”. Będzie to system rezerwowania sal w firmie. Jest to przymiarka do trochę innego zadania, które obecnie nazywam “głównym projektem”.

Architektura – zarys

Mamy dwa główne elementy z których chcemy korzystać. Pierwszy to baza (jakaś, nie koniecznie baza danych) użytkowników, którzy pracują sobie w biurach. Drugi to informacja o salach w poszczególnych lokalizacjach. To spinamy w ramach komponentu zwanego “rezerwacje”. UMLa nie będzie, bo nie chce mi się szukać pluginu do rysowania w WP.
Komponenty mają dobrze zdefiniowane interfejsy i generalnie potrafią się “dogadać” za pomocą REST-WS. I to w praktyce jest jedyne ograniczenie projektowe – jak coś robisz to musi to gadać z resztą po restach i w jsonie. Nie ważne jest czy będzie to pod spodem Java, Railsy, Go, Erlang czy pociąg hindusów. Sposób komunikacji jest jasny i precyzyjny.
Oznacza to, że komponenty będą wobec siebie niezależne na poziomie platformy. Zależności biznesowych się nie pozbędziemy.

Architektura – pomysł na implementację

Skoro całość ma być wzajemnie niezależna to rozsądnym wydaje się wykorzystanie mikroserwisów. Spełniają one warunek wzajemnej niezależności oraz pozwalają na wymuszenie określonej formy komunikacji. Żadnych RMI, żadnych SOAP-ów, a jedynie REST. To nawet COBOL potrafi obsłużyć.
Zatem każdy z modułów będzie sobie śmigał jako niezależny serwis. Oczywiście na poziomie biznesowym będą one zależne, ale awaria jednego z serwisów nie powinna wpłynąć na inne. Co najwyżej wyłączy część funkcjonalności (w myśl zasady, że na pochyłe drzewo i salmonella nie naleje).

Przeprowadźmy zatem krótką analizę zależności na poziomie biznesowym oraz wpływu awarii na poszczególne komponenty.

Użytkownicy (i Sale)

Komponent niezależny. Awaria innych komponentów nie ma na niego wpływu. Ma ukrytą zależność na poziomie implementacji w postaci “jakiegoś” elementu zapisującego dane (baza relacyjna, plik, proviler). Awaria tego elementu spowoduje awarię komponentu.

Rezerwacje

Komponent zależy od dwóch powyższych. Awaria jednego z nich spowoduje ograniczenie możliwości komponentu. Tworzenie i zmiana rezerwacji będzie niemożliwe ponieważ nie będzie można odczytać informacji o salach i użytkownikach. Usuwanie rezerwacji będzie możliwe. Odczyt części informacji o rezerwacji będzie niemożliwy (szczegóły użytkownika/sali).
Komponent ma zależność używaną do składowania danych. Awaria w tym miejscu wyłącza komponent z użycia.

Jak zatem widać współpraca komponentów może oznaczać, że wraz z awarią jednego z nich inne będą miały ograniczone możliwości.

Podsumowanie

Ideę znamy można by to zaimplementować…

Chamberconf 2015 okiem organizatora

January 22nd, 2015

No i się porobiło… na początku gdy luźno sobie z Pawłem, Marcinami i Mateuszem gadaliśmy o zrobieniu wypadu gdzieś za miasto by napić się piwa i pokodować nie sądziłem, że przerodzi się to w konferencję.

Nie sądziłem też, że będę jej współwinnym… znaczy się będę jednym z organizatorów.

Jako uczestnik

Z tej perspektywy mogę powiedzieć tylko tyle, że konferencja się udała. Zarówno prezentacje pierwszego dnia, unconference, integracja jak i dzień drugi były na niezłym poziomie. Największy udział mieli w tym prelegenci i trenerzy, bo to oni przede wszystkim “dają poziom”.
Co mnie osobiście irytowało to rozjechanie się drugiego dnia w ścieżkach. Prezentacje już dawno się skończyły, a warsztaty jeszcze trwały. Cóż… bywa, ale nie sądziłem, że będzie to aż na taką skalę.

Jako organizator

Dużo się nauczyłem o pracy w grupie w przypadku “miękkiego” zadania. Chyba niezłym pomysłem było niezapraszanie sponsorów i zrobienie płatnej konferencji. Dzięki temu mieliśmy pełną swobodę co do organizacji. Nie wiem jak was, ale mnie coraz bardziej zaczynają irytować stoiska firm outsourcingowych. Mam jakieś takie wrażenie, że działa tu deal bezpłatna konferencja za duszę. Może to błędne podejście lecz mam wrażenie, że to wszystko podąża w jakimś złym kierunku. To jednak osobny temat.

Podsumowanie

Chciałbym wszystkim uczestnikom podziękować za te dwa dni dobrej zabawy. Do zobaczenia za rok.

Chamberconf 2015 – rejestracja

January 7th, 2015

Na naszym wrocławsko jugowym meetupie ruszyła rejestracja na Chamberconf 2015.

Zapraszam w imieniu organizatorów :)

Czy twój bitewniak jest zrównoważony?

January 7th, 2015

Poza tym, że rzeźbię sobie kod lubię czasami pograć w gry bitewne. Teraz mam już na to bardzo mało czasu, ale kiedyś było tego więcej. Obecnie z hobby pozostało tylko malowanie ludzików, a i to nie za często.
Niemniej jednak nadal staram się śledzić co dzieje się w świecie. Oznacza to też czytanie blogów. Ostatnio trafiłem na wpis na blogu MX Site poświęcony Prawu Kwadratów Lanchestera (PKL). Jest to chyba najprostszy model pola walki jaki istnieje. Oczywiście na poziomie intuicyjnym. Matematyka to inna inszość… co i jak w oryginalnym poście.

Mnie jednak zastanowiło czy można za pomocą tego prawa w jakiś sposób określić zrównoważenie gry bitewnej. Wszystko w dużym uproszczeniu.

Wprowadzenie teoretyczne do gry

By sprawdzić czy gra jest dobrze zrównoważona za pomocą PKL należy tak dobrać walczące strony by miały równą siłę ognia i liczebność…
Rozpatrzmy walkę dwóch oddziałów Space Marines po 10 żołnierzy w każdym. Nazwijmy je siłami Alfa i Beta. Walkę będziemy rozpatrywać na bazie reguł szóstej edycji W40k (nie mam podręcznika do 7).
Mechanika gry jest oparta o tzw. rzuty kaskadowe. Inaczej mówiąc o rezultacie starcia decyduje seria rzutów tu są to:

  • Rzut na trafienie – reprezentuje umiejętności strzelającego.
  • Rzut na zranienie – reprezentuje siłę ognia broni.
  • Rzut na pancerz – reprezentuje poziom ochrony obrońcy.

W tym modelu by rozstrzygnąć starcie atakujący wykonuje dwa rzuty, a obrońca jeden. Przykładowo Alfa strzela 10k6 (10 kości 6-ściennych), trafia 5 (na pięciu kościach uzyskał wynik większy bądź równy oczekiwanemu). Następnie rzuca na zranienie 5k6 i rani 3 (3 kości >= oczekiwany). Obrońca rzuca 3k6 na pancerz i jeden rzut jest nieudany (wyrzucił mniej oczek niż oczekiwana). Jeden model jest zdejmowany z pola bitwy.

Następnie strony zamieniają się rolami.

Innym rodzajem mechaniki jest mechanika oparta o rzuty przeciwstawne. W jej przypadku każda ze stron wykonuje jeden rzut i modyfikuje go cechami modelu. Takie rozwiązanie wymaga wprowadzenia innego niż równomierny rozkładu prawdopodobieństwa dla wyników rzutu.

Chwila analizy

Już na pierwszy rzut oka widać, że gra nie będzie zrównoważona. Strona broniąca się poniesie straty w pierwszej turze rzutów i jak stanie się stroną atakującą to będzie “na dzień dobry” miała mniejszą siłę ognia.
Dlatego PKL jest tu dobrym narzędziem :) Ponieważ pozwala na porównanie czy nasz system turowy zbliża się do “świata rzeczywistego” gdzie oddziały walczą symultanicznie (wszyscy na raz strzelają).

Rezultaty

Kod możecie sobie pobrać z Githuba. Nas interesuje to rezultat końcowy.

Ogólnie przeprowadziłem 1000000 (milion) symulacji walki. Strona Alfa to atakujący, a Beta broniący. Obie strony to 10 osobowe oddziały SM. Walkę prowadzimy do ostatniego żołnierza.

PKL: ALPHA wins 566 658 times
PKL: BETA wins 433 342 times

Co oznacza, że w około 43% przypadków strona broniąca się ma szansę na zwycięstwo. W40k jest nieźle zrównoważonym systemem… no dobra, zmieńmy trochę liczebność oddziałów. Pytanie brzmi co stanie się gdy zwiększymy liczbę obrońców o 2.

Walka 10:12

PKL: ALPHA wins 277 896 times
PKL: BETA wins 722 104 times

Zatem nie opłaca się atakować przeciwnika silniejszego raptem o 20%. Kolejnym testem jest określenie jak wyposażenie wpływa na wynik walki. W tym celu wyposażę jednego z obrońców w ciężki bolter.

PKL: ALPHA wins 558 199 times
PKL: BETA wins 441 801 times

Dużo to nie dało. Jednak zawsze coś. Po dodaniu kolejnego ciężkiego boltera:

PKL: ALPHA wins 536 463 times
PKL: BETA wins 463 537 times

Co już pozwala na kombinowanie. Nie wiem jakie są obecnie limity broni ciężkiej w oddziale, ale jak podejrzewam można tu trochę ugrać. Szczególnie, że model nie uwzględnia modyfikatorów.

Wnioski

Gra okazuje się całkiem nieźle zrównoważona. Co prawda intuicja podpowiada, że strona atakująca powinna mieć znaczą przewagę, ale w praktyce okazuje się, że kaskadowe rzuty niwelują ją do rozsądnych granic. Jeżeli zatem w trakcie gry okazuje się, że wybitnie ci nie idzie… zmień kostki ;)


Translate »