воскресенье, 1 июня 2008 г.

Luca Turilli


Купил для коллекции диск The Infinite Wonders of Creation (2006). Мне очень нравился ранний Rhapsody (Of Fire нынче), да и сам Люка. Однако, последние альбомы были какие-то однообразные. Но тут...
Тут всё начинается с пения птичек, которых через считанные секунды сносит ураганом. На альбоме два вокала: высокие мужской и женский. Голоса довольно приятны слуху, причём по ходу альбома они то чредуются, то идут параллельно, а то и вовсе сливаются в единое целое. Мелодии красивые и местами очень сильно цепляющие. Аж до дрожи! Темп несколько ниже, чем на ранних работах, но всё равно очень круто.
Рекомендую! Шикарный альбом!

Subterfuge

Забавная позиционная игра, разработанная Diffusion Games. Они опубликовали игру на Armor Games, но там, кажется, битая флешка. Приходится запускать отсюда:

Цель игры - убить вражеского главаря (Leader) и защищать своего всеми силами. Самый крутой воин (Enforcer) убивает всех кроме минёра. Победить его может только только такой же воин или убийца. Убийца (Assassin) также легко убивает всех кроме минёра, но побить его легко. Обычный наёмник (Mercenary) уже погибает при нападении на крутого. Скауты (Scout) легко обезвреживают минёров, а погибая сообщают, от чьеё руки. Минёры (Bomb) сами нападать не могут. Тут главное перехитрить соперника и подставиться под удар кого-нибуть крутого. Ну а главарь может незаметно поменяться с кем-нибудь. Не самое полезное времяпрепровождение.

Жаль на шестом уровне игра зависла: зациклился, считая как выиграть двумя фигурами ;)

четверг, 29 мая 2008 г.

Java Puzzle 94: Lost in the Shuffle

Рассмотрим метод перемешивания содержимого массива. Хорош ли он? Если нет, то как его исправить?
import java.util.Random;
public class Shuffle {
private static Random rnd = new Random();
public static void shuffle(Object[] a) {
for (int i = 0; i < a.length; i++) {
swap(a, i, rnd.nextInt(a.length));
}
}
private static void swap(Object[] a, int i, int j) {
Object tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}

Aвторы доказывают, почему он не достаточно хорош, и рекомендуют использовать библиотечный класс java.utul.Collections, у которого есть метод shuffle. В принципе, достаточно изменить метод так:
  public static void shuffle(Object[] a) {
for (int i = a.length; i > 1; i--) {
swap(a, i - 1, rnd.nextInt(i));
}
}
}

Говорят, что надо читать Кнута. А я у него только второй том осилил ;)

Java Puzzle 93: Class Warfare

Это головоломка тестирует знания совместимости классов. Авторы приводят два класса. В одном определены статические поля, а второй эти поля использует. После компиляции программы авторы предлагают переопределить эти поля в первом классе и перекомпилить его, не компилируя при этом второй. Естественно, результат работы второго класса не изменится.
Это одна из особенностей языка, которые я не люблю: ссылки на константы резолвятся во время компиляции (JLS 13.1). Из-за этого большие проекты приходится перекомпилировать целиком, чтобы не наступить на грабли.

Однако в этой головоломке скрыта другая. Одна из констант в первом классе - null, а согласно JLS 15.28: null не является константой во время компиляции и ссылка на неё резолвится во время исполнения.
Обратите внимание, что enum-константы, введённые в Java 5, не являются константами времени компиляции, т.е. не надо перекомпилировать классы, использующие эти enum-константы, если они поменяются.
Для всех бы констант так!

среда, 28 мая 2008 г.

Ride The Sky


Прикупил первый диск очередного проекта Uli Kusch, бывшего барабанщика Helloween и Masterplan - Ride The Sky: New Protection (2008). Достаточно интересная смесь power и progressive. Мелодии разнообразны и интересны. Исполнение тоже на уровне. Единственное, что меня напрягает, так это барабаны, которые звучат немного громче ожидаемого.
Добротный альбом. Жаль, что Helloween уже не тот. Один Michael Weikath остался...

Tetris

Все знают, зачем нужен SED. Но я ещё не слышал, чтобы его использовали для разработки игр:

Вот тут можно скачать sed-скрипт для игры тетрис, а также sh-скрипт для его запуска. Под cygwin даже работает. Респект!

вторник, 27 мая 2008 г.

Пицца

На выходных Юле захотелось пиццы. И вместо того, чтобы заказать, мы нашли рецепт в Интернете и сделали отличнейшую пиццу:

Несмотря на то, что коржи были магазинные, пицца была очень вкусной. Всё-таки, всё дело в начинке. Это как в анекдоте "не жалейте заварки"!

The Dark Room

Отличная головоломка The Dark Room. Точнее, это 7 головоломок в одной:

Настраивается кнопками Red, Green и Blue. Разные комбинации дают доступ к разным головоломкам. Я прошёл R, G, B, RG и RB. Осталось ещё две - GB и RGB. Доиграть можно потом, так как игра загружает последнее состояние при запуске:

У неё есть продолжение - The Dark Complex, может потом когда-нибудь поиграю...

Русский язык

"Все побежали, и я побежал..." (C)
Прошёл тест по русскому языку, и вот что мне написали:

Вы дали 8 из 8 - Поздравляем, вы - вымирающий вид россиянина, отлично знающего свой родной русский язык. Вы один из немногих носителей элитарного знания, доступного в наше время единицам (7% от общего числа опрошенных). Второй вариант: вы - выпускник, которого хорошо натаскали на сдачу экзамена по русскому языку. Третий вариант: вы – репетитор. Или просто закончили филологический факультет, и пошли работать не по специальности.

Сходи, проверься!

Всё гораздо проще: я учился в СССР!

понедельник, 26 мая 2008 г.

Евровидение

Футбол - взяли, хоккей - взяли. Теперь еще и Евровидение. Кранты стабфонду...
Тут на БОР думали, что же всё-таки подарили Медведеву на инаугурацию: кольцо Всевластья, Мел Судьбы или золотой шар из Зоны кто-то принёс? Сошлись на цветике-семицветике...

Жаль, что финны против Билана опять Lordi не выставили. Зато теперь Билану помогали Евгений Плющенко (без коньков, зато известная фигура) и венгерский скрипач Эдвин Мартон (ничего, что не русский, зато Россия выиграла):

Чтобы улучшить впечатление от песни, народ даже наложил правильный саундтрек. Вы только посмотрите, как Билан на 14-й секунде "ы-ы-ы-ы" тянет:

А, вообще, правильно Владимир Соловьёв пишет на своём блоге. В предыдущие года на нашем телевидении все орали, что Евровидение всё куплено, что там голосуют не качество песни, а за страну и обижались, что какие-то непонятные финны порвали горячо любомого Димочку как Тузик грелку. Сейчас, почему-то, всё это забыто и говорится о каком-то мастерстве нашего исполнителя. Хотя теперь возмущаются британцы.
А вот что было в прямом эфире. Артемий Троицкий аккуратно так (чтобы фанатки не порвали) сказал, что в принципе исполнение было отстойным:

Май в этом году был победный. Россия брала первые места в самых неожиданных местах. Видимо, во всём мире оценили наш парад Победы и решили не рисковать. На всякий случай...

пятница, 23 мая 2008 г.

Бой без правил

Бравый экшн про похождения во Вьетнаме. Спасаемые очкарики бывают полезны: дают новое оружие или помогют переправиться через реку:

Это классический шутер, в котором герой неимоверно крут и легко справляется с толпами врагов:

Если прямо не попасть, то можно закинуть гранату. И не смотрите, что на скриншоте глюк. Это винды снимают не в конце генерации кадра:

Коллега на работе прошёл её и ему показало картинки, созданные на этапе разработки игры:

Мне лично не справиться с управлением, дае если его поменять. Но игрушка сделана с душой. Очень прикольно!

Java Puzzle 92: Twisted Pair

Следующая программа выполняет неестественное действие с анонимным классом. Что она напечатает?
public class Twisted {
private final String name;
public Twisted(String name) {
this.name = name;
}
private String getName() {
return this.name;
}
private void reproduce() {
new Twisted("reproduce") {
private void print() {
System.out.println(getName());
}
}.print();
}
public static void main(String[] args) {
new Twisted("main").reproduce();
}
}

Сначала я подумал, что она совсем не скомпилируется. Потом подумал, что по логике должно напечатать "reproduce". Но и тут чувствуется подвох...
Так было бы, если бы getter не был бы private. Согласно спецификации (JLS 8.2) приватные члены класса никогда не наследуются. Следовательно, из метода print будет вызван метод внешнего (outer) класса, т.е. того класса, экземпляр которого мы создали с именем "main". Соответственно, будет напечатано "main".
Авторы напоминают совет из головоломки 6: если вы не можете с первого взгляда сказать, что делает некая программа, то возможно она делает совсем не то, что вы от нее хотите.

Java Puzzle 91: Serial Killer

А вот объясните-ка, почему сериализация не работает в следующей программе?
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class SerialKiller {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Sub sub = new Sub(666);
sub.check();

ByteArrayOutputStream bos = new ByteArrayOutputStream();
new ObjectOutputStream(bos).writeObject(sub);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Sub copy = (Sub) new ObjectInputStream(bis).readObject();
copy.check();
}
}
class Super implements Serializable {
final Set set = new HashSet();
}
class Sub extends Super {
private int id;
Sub(int id) {
this.id = id;
set.add(this);
}
void check() {
if (!set.contains(this))
throw new Error("invariant");
}
public int hashCode() {
return id;
}
public boolean equals(Object object) {
if (object instanceof Sub) {
Sub that = (Sub) object;
return that.id == this.id;
}
return false;
}
}

Вкратце: если необходимо сериализовать HashSet, HashMap или Hashtable, то надо убедиться в том, что их содержимое (элементы, ключи или значения) не содержат прямых или косвенных ссылок на эти коллекции.
И ещё: если вы разрабатываете сериализуемые классы, то в методах readObject или readResolve избегайте прямого или косвенного вызова методов объектов, которые десериализованы.

Beatallica


В прошлом году скачал MP3 этой группы. Много смеялся. Жуткая смесь музыки и текстов The Beatles и Metallica. Кстати, псевдонимы у музыкантов - такая же смесь: Jaymz Lennfield, Grg Hammetson, Kliff McBurtney и Ringo Larz.
Сегодня увидел в Кайласе - не мог не купить. Это их первый альбом: Sgt. Hetfield's Motorbreath Pub Band (2007). Говорят, в этом году вышел ещё один их альбом: All You Need Is Blood (2008). В нём у них всего одна песня, но исполняется на разных языках, включая русский.
Если нравятся мэтры, а тексты и музыка давно в крови, то рекомендую заслушать этот альбом. Стёбно!

среда, 21 мая 2008 г.

Метро

В метро иногда встречаются неадекватные люди...
Я обычно первым вхожу/выхожу из вагона и этого не замечаю. Сегодня выходил последним и какие-то тётки решили, что я, типа, лох, раз последним выхожу и бросились наперегонки меня обратно в вагон запихивать. Но я человек хотя и мирный, но достаточно тяжёлый. Всё-равно вышел, растолкав их по сторонам.
Я, конечно, понимаю, что они между собой соревновались, кто первый сиденье свободное займёт, но ведь дистанцию надо рассчитывать!

воскресенье, 18 мая 2008 г.

Москва - Питер

Выехали в субботу в 13:30. Решили ехать днём, так как ямы на дороге лучше видно. Правда сложнее было с Мишкой, так как он не спал. Приходилось останавливаться и гулять. В Клину заехали в МакДональдс: купили ему картошки, а себе - мороженое. Погуляли на солнышке. Ещё на какой-то заправке остановились погулять и пофотографироваться на фоне леса. Ну и на Neste опять фломастеры выпросили порисовать. Поэтому ехали долго...
Приехали в 0:50. Всего проехали 753 км со средней скоростью 78 км/ч. Гораздо быстрее, чем в прошлый раз. Потратили 64 литра, т.е. 8,4 литра на 100 километров. Данные по бортовому компьютеру. Он не считает время, пока мы гуляем, а двигатель выключен...

Пятнично

В прошедшую пятницу у нас в конторе проходил очередной beer bash. Раз в месяц пива разливного привозят, в основном от частных пивоварен. Пиво на вкус было слишком кислым для меня, но и не те помои, что обычно в магазинах продают. По крайней мере после трёх литров голова с утра не болела. Единственный минус, что после поехал в Москву за семьёй и в поезде забыл жилетку. На пьянке наша команда оккупировала караоке и тупо орала песни. Я тоже орал... ;)
Перед всем этим были конкурсы, типа, кто быстрее пива выпьет. Так один парень прямо в горло заливал. Секунд за 5 бутылку усосал ;)
Ещё, оказывается, в приглашении говорилось, что будет конкурс стихов и надо написать что-нибудь. А я это прозевал. Зато чел из нашей команды отличился (mr. JFileChooser):

    Сан. Пятница. Коллеги. Пиво.
    Бессмысленный и мощный гвалт.
    Всего лишь месяц перерыва -
    И снова так. Тому я рад!

    Уедешь в отпуск - как тоскливо!
    И будут сниться по ночам
    Гвалт, разливные реки пива,
    Коллеги, пятница и Сан.

Мне аж завидно стало. Какой талантище! Как верно всё подметил. Ну я и написал в ответ, хотя и не так круто, зато тоже правдиво:

    Леонид отжёг сегодня -
    Стих забавный написал.
    Ну а я забыл про конкурс
    И, конечно, опоздал...

четверг, 15 мая 2008 г.

Crematory


Прикупил альбом Pray (2008). Офигеть! Стало ещё лучше предыдущего альбома. Одни сплошные хиты, даже не знаю, что выделить. Наверное надо отметить композицию Sleeping Solution, которая мне каждый раз напоминает Tears os Time. Но и остальные не подкачали...
Отличные, хорошо запоминающиеся мелодии. Гроулинг Феликса идеально сбалансирован с чистым вокалом Маттиаса. Много клавишных, но, как обычно, жёсткие гитарные риффы.
Мне даже сложно выбрать любимый диск. Раньше это был альбом Illusions (1995) однозначно. Теперь я уже сомневаюсь...
Категорически рекомендую!

среда, 14 мая 2008 г.

Java Puzzle 90: It's Absurd, It's Pain, It's Superclass

Следующая программа очень простая и ничего не делает. Но к ней есть два вопроса: почему она не компилируется и как это исправить?
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {}
}

Проблема в том, что при создании класса вызывается "конструктор по-умолчанию", который создаётся автоматически и содержит вызов конструктора суперкласса, а этот вызов выглядит так: this.super(). Теперь становится понятно, почему компилятор ругается "cannot reference this before supertype constructor has been called". Это запрещено согласно спецификации (JLS 8.8.7.1). А исправить можно добавив конструктор без параметров в класс Inner2:
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {
Inner2() {
Outer.this.super();
}
}
}

Такая конструкция уже компилируется, хотя и выглядит очень странно. Кстати, парсер IntelliJ IDEA продолжает показывать ошибку в этом месте.
Авторы предлагают решение лучше и советуют: Когда вы пишете вложенный класс спросите себя, действительно ли нужен доступ к членам класса, в который вы его вкладываете? Если нет, то делайте вложенный класс статическим. Я вообще не люблю вложенные классы. Они усложняют работу с наследованием, а так же с generics и reflection.

Java Puzzle 89: Generic Drugs

В предыдущей задаче мы поняли, что не надо использовать raw type. Написали программу, расставив везде нужные декларации. Что напечатает следующая программа?
public class LinkedList {
private Node head;
private class Node {
E value;
Node next;
Node(E value) {
this.value = value;
this.next = head;
head = this;
}
}
public void add(E e) {
new Node(e);
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.value + " ");
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("world");
list.add("Hello");
list.dump();
}
}

А она не хочет компилиться! Дело в том, что типы E разные для класса LinkedList и класса Node. Избегайте затенения параметра типа. Авторы говорили об опасности затенения в головоломках 71, 73 и 79. После этого сразу видно, что надо добавить второй параметр конструктору класса Node и слегка изменить метод add:
public class LinkedList {
private Node head;
private class Node {
F value;
Node next;
Node(F value, Node next) {
this.value = value;
this.next = next;
}
}
public void add(E e) {
this.head = new Node(e, this.head);
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.value + " ");
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("world");
list.add("Hello");
list.dump();
}
}

Блин, с этими generics, как по минному полю ходишь. Хотя с template классами в C++ тоже не так всё просто...