12
\$\begingroup\$

Golf Wars enter image description here Background theme

Introduction

Obi-Wan Kenobi, Qui-Gon Jinn and Darth Maul are about to fight! However, they've all forgotten to bring their respective lightsabers. Write a program or function which, given the string Jedi as input, generates an image similar to this*:

enter image description here

and given the string Sith, generates an image similar to this:

enter image description here

Images specifications

  • Any of the 3 lightsabers (the white blade including the round edge at the end(2 round edges for the red one) and including the handle) is 900px long (This does not include the color gradient around the blade).

  • The round edge at the end of the blade is a halfcircle (a discrete approximation of it, obviously) with a diameter equal to the width of the blade.

  • The blade (i.e. the white part of the lightsaber) is 12px wide.

  • The green and blue lightsabers are separated by 200 px (from the center line of the green blade to the center line of the blue blade).

  • The handle for all 3 lightsabers is 180px (1/5 of the total length). Therefore the blade itself including the round edge(s) is 720px long for the blue and green lightsabers and 360px long for the two blades of the red lightsaber.

  • The handle for the blue and green lightsabers is at the bottom of the lightsaber. The handle for the red lightsaber is horizontaly centered.

  • The length of the gradient from the edge of the white blade to a completely white color is 1.5 * the width of the blade (e.g. 18px for the linear parts).

  • The green gradient goes from RGB (0,255,0) to white (255,255,255) (or transparent if it's easier for you to implement). The red gradient goes from (255,0,0) to white, and the blue gradient goes from (0,0,255) to white.

  • The color of the handle is RGB (128,128,128).

  • There can be white empty space around the lightsaber(s).

Inputs

Either Sith or Jedi as a string. You can take this string from STDIN, as a function argument, command line parameter, or anything similar. You may assume that the input will always be exactly Sith or Jedi and nothing else.

Output

You must generate an image file containing the image corresponding to the input string. You are relatively free to choose whatever image format you want, as long as it is a True Color image.

Scoring

This is , so the shortest answer in bytes wins. May the force be with you.


* The images in this post are not displayed full size.

\$\endgroup\$
3
  • \$\begingroup\$ Do we have to save the file to disk or can we write it to stdout? What about just displaying it on screen? \$\endgroup\$ Commented Aug 13, 2015 at 12:24
  • \$\begingroup\$ Displaying it on screen is fine, if your language can do that easily. As for writing the file itself to STDOUT, I guess it's acceptable for languages which can't easily save files to disk \$\endgroup\$
    – Fatalize
    Commented Aug 13, 2015 at 12:28
  • \$\begingroup\$ I think the title should be Golf Wars Episode I: The Phantom Dennis. \$\endgroup\$
    – mbomb007
    Commented Dec 12, 2016 at 15:01

1 Answer 1

9
\$\begingroup\$

HTML/CSS solution, 765 740 541 bytes

<style>[id]:not(:target){display:none}table{width:900px;height:12px;border-spacing:0}td:last-child{border-radius:0 12px 12px 0}#Sith td:first-child{border-radius:12px 0 0 12px}#Sith td{box-shadow:0 0 18px red}#Jedi{transform:rotate(-90deg);margin:350px 0}#Jedi td{box-shadow:0 0 18px #0f0}*+table{margin:200px 0 0 0}#Jedi *+table td{box-shadow:0 0 18px #00f}td:nth-last-child(2){background:#888;width:180px;box-shadow:none!important}</style><div id=Jedi><table><td><td></table><table><td><td></table></div><table id=Sith><td><td><td></table>

The recent refactor uses the :target pseudo-class rather than a <form> and Javascript.

To enter either input, add it to the end of the URL as a target, e.g. test.html#Jedi or test.html#Sith

Here it is again with whitespace and a few comments:

<style>
  /* hide all but the anchored lightsaber (only lightsabers have ids) */
  [id]:not(:target) { display:none }

  /* tables are lightsabers */
  table { width:900px; height:12px; border-spacing:0 }
  td:last-child { border-radius:0 12px 12px 0 } /* curved tip */
  #Sith td:first-child { border-radius:12px 0 0 12px } /* 2nd curved tip */
  #Sith td { box-shadow:0 0 18px red }
  #Jedi { transform:rotate(-90deg); margin:350px 0 }
  #Jedi td { box-shadow:0 0 18px #0f0 } /* green */
  * + table { margin:200px 0 0 0 } /* gap between Jedi lightsabers */
  #Jedi * + table td { box-shadow:0 0 18px #00f } /* blue */
  /* handles */
  td:nth-last-child(2) {
    background:#888; width:180px; box-shadow:none!important }
</style>
<div id=Jedi>
  <table><td><td></table>
  <table><td><td></table>
</div>
<table id=Sith><td><td><td></table>

The lightsabers are <table> elements with one cell per part (blade/handle) that are unhidden via their id attributes.

The blades are colored with CSS box-shadows and the Jedi lightsabers undergo a transform: rotate().

Pictures or it didn't happen (click for full res):

If you add td{background:#fff}body{background:#000} to the CSS, you'll get a cool dark view.

Tested in Firefox and Chrome (on Linux). Note that this is not at all standards-compliant, as I was trying to shrink the size as much as possible.

Thanks to @manatwork for border-spacing and :target.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ You could use the :target pseudo-class, like I did once. pastebin.com/WtxbSsr3 then access it like file:///tmp/test.html#Jedi and file:///tmp/test.html#Sith (BTW, the HTML cellspacing=0 → CSS border-spacing:0 change looks correct in my Firefox, but not checked in other browsers.) \$\endgroup\$
    – manatwork
    Commented Aug 15, 2015 at 11:27
  • \$\begingroup\$ Thanks, I've been looking for border-spacing for a long time (this saved 25 chars). The :target advice allowed removing the <form> and all JS. In my last edit, I also tightened it up even further. It could get smaller still if we use <hr> with float:left and clear:left, but this should do. \$\endgroup\$
    – Adam Katz
    Commented Aug 15, 2015 at 12:28
  • 1
    \$\begingroup\$ It will still work if you delete the first and last chars: style>[id]:not(:target){display:none}table{width:900px;height:12px;border-spacing:0}td:last-child{border-radius:0 12px 12px 0}#Sith td:first-child{border-radius:12px 0 0 12px}#Sith td{box-shadow:0 0 18px red}#Jedi{transform:rotate(-90deg);margin:350px 0}#Jedi td{box-shadow:0 0 18px #0f0}*+table{margin:200px 0 0 0}#Jedi *+table td{box-shadow:0 0 18px #00f}td:nth-last-child(2){background:#888;width:180px;box-shadow:none!important}</style><div id=Jedi><table><td><td></table><table><td><td></table></div><table id=Sith><td><td><td></table \$\endgroup\$
    – user60199
    Commented Nov 13, 2016 at 12:51
  • 1
    \$\begingroup\$ @RudolfL.Jelínek That's crazy! I'm not comfortable with that shortcut, and I'm not sure of how many browsers support it, but if it is universally supported, you've successfully cut two characters off of the code. There are other tweaks that would similarly shave off a bit here and there with only minimal visual degradation, including the potential of using <hr>s in place of <table>s. \$\endgroup\$
    – Adam Katz
    Commented Nov 13, 2016 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.