package readers ;
import java.awt.Color ;
import java.awt.Graphics2D ;
import java.awt.image.BufferedImage ;
import java.io.File ;
import java.io.IOException ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.regex.Pattern ;
import javax.imageio.ImageIO ;
import readers.fonts.Font ;
import readers.fonts.Glyph ;
public class SoundVoltexReader extends Reader {
final static int REGION_PADDING = 32 ;
List < Box > extraRegions = new ArrayList < > ( ) ;
static int lastJump = 0 ;
boolean effectiveRate = false ;
boolean failed = false ;
public SoundVoltexReader ( ) {
addRegion ( new Box ( 385 , 1006 , 454 , 29 ) ) ; //title[0]
addRegion ( new Box ( 476 , 1075 , 242 , 57 ) , NUMBER ) ; //bigscore[1]
addRegion ( new Box ( 717 , 1096 , 146 , 34 ) , NUMBER ) ; //score[2]
addRegion ( new Box ( 630 , 1142 , 110 , 16 ) , NUMBER ) ; //exscore[3]
addRegion ( new Box ( 932 , 1194 , 55 , 19 ) ) ; //health percentage[4]
addRegion ( new Box ( 617 , 1237 , 70 , 23 ) , NUMBER ) ; //early error[5]
addRegion ( new Box ( 617 , 1268 , 70 , 23 ) , NUMBER ) ; //early near[6]
addRegion ( new Box ( 617 , 1300 , 70 , 23 ) , NUMBER ) ; //early critical[7]
addRegion ( new Box ( 617 , 1330 , 70 , 23 ) , NUMBER ) ; //s-critical[8]
addRegion ( new Box ( 617 , 1362 , 70 , 23 ) , NUMBER ) ; //late critical[9]
addRegion ( new Box ( 617 , 1393 , 70 , 23 ) , NUMBER ) ; //late near[10]
addRegion ( new Box ( 617 , 1424 , 70 , 23 ) , NUMBER ) ; //late error[11]
addRegion ( new Box ( 188 , 1231 , 70 , 23 ) , NUMBER ) ; //chip s-critical[12]
addRegion ( new Box ( 188 , 1262 , 70 , 23 ) , NUMBER ) ; //chip critical[13]
addRegion ( new Box ( 188 , 1294 , 70 , 23 ) , NUMBER ) ; //chip near[14]
addRegion ( new Box ( 188 , 1324 , 70 , 23 ) , NUMBER ) ; //chip error[15]
addRegion ( new Box ( 266 , 1231 , 70 , 23 ) , NUMBER ) ; //long s-critical[16]
addRegion ( new Box ( 266 , 1324 , 70 , 23 ) , NUMBER ) ; //long error[17]
addRegion ( new Box ( 345 , 1231 , 70 , 23 ) , NUMBER ) ; //vol s-critical[18]
addRegion ( new Box ( 345 , 1324 , 70 , 23 ) , NUMBER ) ; //vol error[19]
addRegion ( new Box ( 304 , 1364 , 70 , 23 ) , NUMBER ) ; //max combo[20]
addRegion ( new Box ( 58 , 862 , 132 , 26 ) ) ; //difficulty[21]
addRegion ( new Box ( 875 , 1046 , 125 , 82 ) ) ; //rating[22]
extraRegions . add ( new Box ( 531 , 1152 , 75 , 16 ) ) ; //EX Score text[0]
extraRegions . add ( new Box ( 753 , 1197 , 150 , 16 ) ) ; //effective rate text[1]
extraRegions . add ( new Box ( 499 , 1238 , 78 , 23 ) ) ; //early error text[2]
extraRegions . add ( new Box ( 499 , 1268 , 78 , 23 ) ) ; //early near text[3]
extraRegions . add ( new Box ( 499 , 1300 , 93 , 23 ) ) ; //early critical text[4]
extraRegions . add ( new Box ( 499 , 1332 , 108 , 23 ) ) ; //s-critical text[5]
extraRegions . add ( new Box ( 499 , 1362 , 93 , 23 ) ) ; //late critical text[6]
extraRegions . add ( new Box ( 499 , 1393 , 78 , 23 ) ) ; //late near text[7]
extraRegions . add ( new Box ( 499 , 1424 , 78 , 23 ) ) ; //late error text[8]
extraRegions . add ( new Box ( 62 , 1230 , 119 , 24 ) ) ; //s-critical extra text[9]
extraRegions . add ( new Box ( 62 , 1262 , 119 , 24 ) ) ; //critical extra text[10]
extraRegions . add ( new Box ( 62 , 1294 , 119 , 24 ) ) ; //near extra text[11]
extraRegions . add ( new Box ( 62 , 1325 , 119 , 24 ) ) ; //error extra text[12]
extraRegions . add ( new Box ( 62 , 1230 , 119 , 24 ) ) ; //s-critical extra text[13]
extraRegions . add ( new Box ( 62 , 1325 , 119 , 24 ) ) ; //error extra text[14]
extraRegions . add ( new Box ( 62 , 1230 , 119 , 24 ) ) ; //s-critical extra text[15]
extraRegions . add ( new Box ( 62 , 1325 , 119 , 24 ) ) ; //error extra text[16]
extraRegions . add ( new Box ( 71 , 1365 , 171 , 22 ) ) ; //maximum chain text[17]
init ( ) ;
}
void ColorFilter ( int [ ] arr , int region , int width ) {
switch ( region ) {
case 0 : {
final ColorRange TARGETCOLOR = new ColorRange ( 240 , 255 , 240 , 255 , 240 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 100 , 255 , 100 , 255 , 100 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 1 :
case 2 : {
final ColorRange TARGETCOLOR = new ColorRange ( 160 , 255 , 170 , 255 , 190 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 26 , 255 , 53 , 255 , 80 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 3 : {
final ColorRange TARGETCOLOR = new ColorRange ( 230 , 255 , 180 , 255 , 20 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 180 , 255 , 140 , 255 , 15 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 17 :
case 18 :
case 19 :
case 20 : {
final ColorRange TARGETCOLOR = new ColorRange ( 200 , 255 , 200 , 255 , 200 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 21 : {
final ColorRange TARGETCOLOR = new ColorRange ( 200 , 255 , 200 , 255 , 200 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 400 :
{
final ColorRange TARGETCOLOR = new ColorRange ( 200 , 255 , 150 , 255 , 0 , 50 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 100 , 255 , 60 , 255 , 0 , 50 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 401 :
{
final ColorRange TARGETCOLOR = new ColorRange ( 0 , 60 , 0 , 100 , 0 , 100 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 0 , 100 , 0 , 180 , 0 , 180 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 402 :
case 403 :
case 407 :
case 408 :
case 411 :
case 412 :
case 414 :
case 416 : //Error/Near
{
final ColorRange TARGETCOLOR = new ColorRange ( 240 , 255 , 240 , 255 , 240 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 404 :
case 406 :
case 410 : //Critical
{
final ColorRange TARGETCOLOR = new ColorRange ( 200 , 255 , 190 , 255 , 140 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 405 :
case 409 :
case 413 :
case 415 : //S-Critical
{
final ColorRange TARGETCOLOR = new ColorRange ( 200 , 255 , 200 , 255 , 0 , 50 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
case 417 :
{
final ColorRange TARGETCOLOR = new ColorRange ( 230 , 255 , 230 , 255 , 230 , 255 ) ;
final ColorRange SEEKINGCOLOR = new ColorRange ( 120 , 255 , 120 , 255 , 120 , 255 ) ;
final Color FINALCOLOR = Color . MAGENTA ;
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( TARGETCOLOR . colorInRange ( col ) ) {
seek ( arr , i , SEEKINGCOLOR , FINALCOLOR , width ) ;
}
}
for ( int i = 0 ; i < arr . length ; i + + ) {
Color col = new Color ( arr [ i ] , true ) ;
if ( ! col . equals ( Color . MAGENTA ) ) {
arr [ i ] = TRANSPARENT ;
}
}
} break ;
}
}
public void interpretBoxes ( Path img , boolean testingMode ) {
/ * String dataString = readAllBoxes ( img ) ;
String [ ] data = dataString . split ( Pattern . quote ( "\n" ) ) ;
String [ ] ja_data = data [ 0 ] . split ( Pattern . quote ( ")" ) ) ;
String [ ] en_data = data [ 2 ] . split ( Pattern . quote ( ")" ) ) ;
trimAllData ( ja_data ) ;
trimAllData ( en_data ) ;
System . out . println ( Arrays . toString ( ja_data ) ) ;
System . out . println ( Arrays . toString ( en_data ) ) ; * /
int regionHeights = 0 ;
int maxWidth = 0 ;
int counter = 0 ;
for ( int i = 0 ; i < readRegions . size ( ) ; i + + ) {
regionHeights + = readRegions . get ( i ) . h + REGION_PADDING ;
if ( readRegions . get ( i ) . w > maxWidth ) {
maxWidth = readRegions . get ( i ) . w ;
}
}
try {
BufferedImage originalImg = ImageIO . read ( img . toFile ( ) ) ;
BufferedImage cutImg = new BufferedImage ( maxWidth , regionHeights , BufferedImage . TYPE_INT_ARGB ) ;
Graphics2D g = cutImg . createGraphics ( ) ;
int currentHeight = 0 ;
for ( int i = 0 ; i < readRegions . size ( ) ; i + + ) {
BufferedImage subRegion = new BufferedImage ( readRegions . get ( i ) . w , readRegions . get ( i ) . h , BufferedImage . TYPE_INT_ARGB ) ;
subRegion . setRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , originalImg . getRGB ( readRegions . get ( i ) . x , readRegions . get ( i ) . y , readRegions . get ( i ) . w , readRegions . get ( i ) . h , null , 0 , readRegions . get ( i ) . w ) , 0 , readRegions . get ( i ) . w ) ;
int [ ] arr = subRegion . getRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , null , 0 , readRegions . get ( i ) . w ) ;
//System.out.println(Arrays.toString(arr));
//System.out.println(i);
//ImageIO.write(originalImg.getSubimage(readRegions.get(i).x, readRegions.get(i).y, readRegions.get(i).w, readRegions.get(i).h),"png",new File("cut.png"));
ColorFilter ( arr , i , readRegions . get ( i ) . w ) ;
subRegion . setRGB ( 0 , 0 , readRegions . get ( i ) . w , readRegions . get ( i ) . h , arr , 0 , readRegions . get ( i ) . w ) ;
ImageIO . write ( subRegion , "png" , new File ( "sub.png" ) ) ;
cutImg . setRGB ( 0 , currentHeight , readRegions . get ( i ) . w , readRegions . get ( i ) . h , arr , 0 , readRegions . get ( i ) . w ) ;
String val = interpretImage ( subRegion , i ) ;
sig_data [ counter + + ] = val ;
currentHeight + = readRegions . get ( i ) . h + REGION_PADDING ;
}
//695,933 140,8,8
final ColorRange failRange = new ColorRange ( 135 , 180 , 0 , 15 , 0 , 15 ) ;
if ( failRange . colorInRange ( new Color ( originalImg . getRGB ( 695 , 933 ) ) ) ) {
failed = true ;
}
//912,1204
Color col = new Color ( originalImg . getRGB ( 912 , 1204 ) , true ) ;
ColorRange range = new ColorRange ( 90 , 110 , 225 , 245 , 250 , 255 ) ;
if ( range . colorInRange ( col ) ) {
effectiveRate = true ;
}
Path output = Paths . get ( "result.png" ) ;
ImageIO . write ( cutImg , "png" , output . toFile ( ) ) ;
if ( testingMode ) {
interpretOutput ( new String [ ] { } , new String [ ] { } , sig_data ) ;
} else {
String dataString = readAllBoxes ( output ) ;
String [ ] data = dataString . split ( Pattern . quote ( "\n" ) ) ;
String [ ] ja_data = parseOutCommas ( data [ 0 ] ) . split ( Pattern . quote ( "," ) ) ;
String [ ] en_data = parseOutCommas ( data [ 2 ] ) . split ( Pattern . quote ( "," ) ) ;
trimAllData ( ja_data ) ;
trimAllData ( en_data ) ;
System . out . println ( Arrays . toString ( ja_data ) ) ;
System . out . println ( Arrays . toString ( en_data ) ) ;
System . out . println ( Arrays . toString ( sig_data ) ) ;
interpretOutput ( ja_data , en_data , sig_data ) ;
}
g . dispose ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
//System.out.println(data[0]);
//System.out.println(data[2]);
}
private String interpretImage ( BufferedImage cutImg , int i ) {
switch ( i ) {
case 1 : {
Font f = Font . FONT_SDVX_BIGSCORE ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
case 2 : {
Font f = Font . FONT_SDVX_LITTLESCORE ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
case 3 : {
Font f = Font . FONT_SDVX_EXSCORE ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 17 :
case 18 :
case 19 :
case 20 : {
Font f = Font . FONT_SDVX_NOTECOUNT ;
List < Glyph > glyphs = Glyph . split ( cutImg ) ;
return f . convertGlyphs ( glyphs ) ;
}
}
return "" ;
}
String interpretResults ( String [ ] finalData ) {
for ( int i = 0 ; i < finalData . length ; i + + ) {
String [ ] splitter = finalData [ i ] . split ( Pattern . quote ( "\n" ) ) ;
switch ( i ) {
case 0 : {
title = convertToString ( splitter ) ;
} break ;
case 1 : {
score = convertToInt ( splitter ) ;
} break ;
case 2 : {
String score2 = convertToString ( splitter ) ;
score = convertToInt ( new String [ ] { Integer . toString ( score ) , score2 } ) ;
} break ;
case 3 : {
other + = "{ex:" + Integer . toString ( convertToInt ( "EX SCORE" , splitter ) ) + "," ;
} break ;
case 4 : {
pct = convertToDouble ( splitter ) ; //We're lucky excessive and effective rate have the same number of characters...
/ * if ( effectiveRate & & pct < 70 ) {
failed = true ;
} * /
} break ;
case 5 : {
notes [ 0 ] = convertToInt ( "ERROR" , splitter ) ;
} break ;
case 6 : {
notes [ 1 ] = convertToInt ( "NEAR" , splitter ) ;
} break ;
case 7 : {
notes [ 2 ] = convertToInt ( "CRITICAL" , splitter ) ;
} break ;
case 8 : {
notes [ 3 ] = convertToInt ( "S-CRITICAL" , splitter ) ;
} break ;
case 9 : {
notes [ 4 ] = convertToInt ( "CRITICAL" , splitter ) ;
} break ;
case 10 : {
notes [ 5 ] = convertToInt ( "NEAR" , splitter ) ;
} break ;
case 11 : {
notes [ 6 ] = convertToInt ( "ERROR" , splitter ) ;
} break ;
case 12 : {
other + = "chip_scritical:" + Integer . toString ( convertToInt ( "S-Critical" , splitter ) ) + "," ;
} break ;
case 13 : {
other + = "chip_critical:" + Integer . toString ( convertToInt ( "Critical" , splitter ) ) + "," ;
} break ;
case 14 : {
other + = "chip_near:" + Integer . toString ( convertToInt ( "NEAR" , splitter ) ) + "," ;
} break ;
case 15 : {
other + = "chip_error:" + Integer . toString ( convertToInt ( "ERROR" , splitter ) ) + "," ;
} break ;
case 16 : {
other + = "long_scritical:" + Integer . toString ( convertToInt ( "S-Critical" , splitter ) ) + "," ;
} break ;
case 17 : {
other + = "long_error:" + Integer . toString ( convertToInt ( "ERROR" , splitter ) ) + "," ;
} break ;
case 18 : {
other + = "vol_scritical:" + Integer . toString ( convertToInt ( "S-CRITICAL" , splitter ) ) + "," ;
} break ;
case 19 : {
other + = "vol_error:" + Integer . toString ( convertToInt ( "ERROR" , splitter ) ) + "," ;
} break ;
case 20 : {
maxcombo = convertToInt ( "MAXIMUM CHAIN" , splitter ) ;
} break ;
case 21 : {
difficulty = convertToInt ( "EXH" , splitter ) ;
} break ;
case 22 : {
other + = "failed:" + failed + "}" ;
if ( score > = 9900000 ) { rank = 0 ; /*S*/ } else
if ( score > = 9800000 ) { rank = 1 ; /*AAA+*/ } else
if ( score > = 9700000 ) { rank = 2 ; /*AAA*/ } else
if ( score > = 9500000 ) { rank = 3 ; /*AA+*/ } else
if ( score > = 9300000 ) { rank = 4 ; /*AA*/ } else
if ( score > = 9000000 ) { rank = 5 ; /*A+*/ } else
if ( score > = 8700000 ) { rank = 6 ; /*A*/ } else
if ( score > = 8000000 ) { rank = 7 ; /*B*/ } else
if ( score > = 7000000 ) { rank = 8 ; /*C*/ } else
{ rank = 9 ; /*D*/ }
} break ;
}
}
return toString ( ) ;
}
}